hdu 4630 no pain no game 樹狀數組+離線查詢

來源:互聯網
上載者:User

理解好這道題的樹狀數組所代表的含義是解題的關鍵,可是網上的題解都沒點出其樹狀數組的含義(難道是大家都覺得太簡單了嗎=_=),然後我看題解都看不會,這兩天切了幾道簡單的同類型題,有所收穫。    反正我第一次想通這類樹狀數組的含義時是挺orz的...下面記錄是建立在對樹狀數組的Update/Query過程已經有一個感性的理解的條件之上的。



    Update(p, value) 的含義不是更新[1,p]這段區間的最大gcd值

    相應地,c[p]的含義不是[1,p]這段區間的最大gcd值,Query(p)不是表示查詢[1,p]這段區間的最大gcd值.

    這幾乎是“樹狀數組+離線詢問”這類題目的共性了,這道題中的c[p]表示區間[1..p, i..∞]的最大gcd,即左端點為1到p,右端點為i到無窮大(其中i表示掃描到的當前位置,具體的還得看實現)。相應地Update(pos,
value)在含義上應理解為更新[pos, i..∞]的最大gcd值(想一想,為什麼);要理解Update()為什麼要賦予如此含義,還得理解好Query()的含義,這裡Query(p)的傳回值應為“[p, i]的最大gcd”。

     基本上所有解法都是上述定義,不過可以有不同種實現方法。我最近就發現我做過的幾道題把它們的Update/Query的方向倒過來,再改改插入/刪除的操作,同樣可以AC~這個看個人喜好。

      

    

     樹狀數組+離線的大致套路:按右端點離線排序詢問,從左往右掃序列,根據Update/Query的方向進行相應更新,遇到i == query[i].r 則算出 答案。c[p]表示區間[1..p, i..∞]或者[p, i..∞]的和/最值,即左端點為1到p,右端點為i到無窮大。pre[0]是堆拉圾的地方.

本題的解法網上已有很多,不贅述了,其實只要理解好樹狀數組的含義,再看題解,是很簡單的。


#include <algorithm>#include <vector>#include <string.h>#include <stdio.h>using namespace std;#define         MAXN        50005#define         N           50000#define         low(x)      ((x) & (-(x)))int a[MAXN], c[MAXN], ans[MAXN], pre[MAXN];struct Quetion {    int l, r, id;} que[MAXN];vector<int> factor[MAXN];int n, query;void get_factor(){    for(int i = 1; i <= N; i++)        for(int j = i; j <= N; j += i)            factor[j].push_back(i);}bool cmp(const Quetion & a, const Quetion & b) {    return a.r < b.r;}void init(){    memset(c, 0, sizeof(c));    memset(pre, 0, sizeof(pre));}void Update(int pos, int value){    while(pos) {                    //TODO   注意方向!!!        c[pos] = max(c[pos], value);        pos -= low(pos);    }}int Query(int pos){    int value = 0;    while(pos <= n) {               //TODO   注意方向!!!        value = max(value, c[pos]);        pos += low(pos);    }    return value;}int main(){    int cases;    get_factor();    scanf("%d", &cases);    while(cases--) {        scanf("%d", &n);        init();        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);        scanf("%d", &query);        for(int i = 0; i < query; i++) {            scanf("%d%d", &que[i].l, &que[i].r);            que[i].id = i;        }        sort(que, que+query, cmp);        int j = 0;        for(int i = 1; i <= n; i++) {            int & x = a[i];            for(int Size = factor[x].size(), k = 0; k < Size; k++) {                int fac = factor[x][k];                if(pre[fac] != 0) {                    Update(pre[fac], fac);                }                pre[fac] = i;            }            while(j < query && que[j].r == i) {                ans[que[j].id] = Query(que[j].l);                j++;            }        }        for(int i = 0; i < query; i++) printf("%d\n", ans[i]);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.