• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            算法學社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0
            題目描述:
               給長度為20000的序列。求左端點在[a,b]和右端點在[c,d]中所有的子序列,最大的中位數。
            吐槽:
                1. 照著CLJ的標程和題解一點點看,終于弄懂了主席樹。。。。(即可持久化線段樹)
                2. 函數式編程V5。。。。。
                3. 劃分樹已經成為時代的眼淚了。。。。
            算法分析:
                大家自己去看CLJ的論文吧。。。。。。
            #include<iostream>
            #include<cstdio>
            #include<algorithm>
            #include<cstring>
            using namespace std;
            const int N = 20005;
            struct info{
                int sum, mxl, mxr;
                info(){}
                info(int val){
                    sum = mxl = mxr = val;
                }
            };
            info operator + (const info l, const info r){
                info mid ;
                mid .sum = l.sum + r.sum;
                mid .mxl = max(l.mxl , l.sum + max(r.mxl, 0 ));
                mid .mxr = max(r.mxr , r.sum + max(l.mxr, 0 ));
                return mid;
            }
            struct tree{
                int l,r;
                tree *pl, *pr;
                info v;
                tree (int _l, int _r, tree *_pl, tree *_pr)
                : l(_l), r(_r), pl (_pl), pr(_pr){
                    v = pl->v + pr->v;
                }
                tree (int _l, int _r, int val): l(_l), r(_r){
                    if(_l == _r) {
                        v = info(val);
                        return ;
                    }
                    int mid = l + r >>1;
                    pl = new tree(l, mid, val);
                    pr = new tree(mid+1, r, val);
                    v = pl->v + pr->v;
                }
                info ask(int L,int R){
            //        cout<<L<<" "<<R<<" "<<l<<" "<<r<<endl;
                    if(L <= l && R >= r){
            //            cout<<l<<" "<<r<<" "<<v.mxl<<" "<<v.sum<<" "<<v.mxr<<endl;
                        return v;
                    }
                    int mid = l + r >> 1;
                    if(mid < L) return pr->ask(L,R);
                    else if(mid >= R) return pl->ask(L,R);
                    else return pl ->ask(L,R) + pr ->ask(L,R);
                }
                tree* change(int pos, int val){
                    if(l == r){
                        return new tree(l,r,val);
                    }
                    int mid = l+r >>1;
                    if(pos <= mid) return new tree(l,r,pl->change(pos,val),pr);
                    return new tree(l,r,pl,pr->change(pos,val));
                }
                void OP(){
                    cout<<l<<" "<<r<<" "<<v.mxl<<" "<<v.sum<<" "<<v.mxr<<endl;
                    if(l==r) return;
                    pl->OP();
                    pr->OP();
                }
            };
            tree *root[N];
            pair<int,int> num[N];
            int a[N],n;
            bool chk(int m,int a,int b,int c,int d){
                tree *rt = root[m];
                int val =  rt->ask(a, b).mxr + (b+1<c ? rt->ask(b+1,c-1).sum : 0) + rt -> ask(c,d).mxl ;
                //cout<<val<<endl;
                return val >= 0;
            }
            int main(){
                scanf("%d",&n);
                for(int i=0;i<n;i++){
                    scanf("%d",&a[i]);
                    num[i] = make_pair(a[i],i);
                }
                sort(num,num+n);
                root[0] = new tree(0,n-1,1);
                //for(int i=0;i<n;i++) cout<<num[i].first <<" "<<num[i].second <<" "; cout<<endl;
                for(int i=1;i<n;i++){
            //        cout<<"i: "<<i<<" "<<num[i-1].second<<endl;
                    root[i] = root[i-1] -> change(num[i-1].second, -1);
            //        root[i]->OP();
                }
                int Q, last = 0;
                cin >>Q;
                while(Q--){
                    int q[4];
                    for(int i=0;i<4;i++){
                        scanf("%d",&q[i]);
                        q[i] = (q[i] + last) % n;
                    }
                    sort(q,q+4);
                    int l = 0, r = n;
                    while(l < r){
                        int m = l+ r>>1;
                //        cout<<m<<" "<<q[0]<<" "<<q[1]<<" "<<q[2]<<" "<<q[3]<<endl;
                        if(chk(m,q[0],q[1],q[2],q[3])) l = m+1;
                        else r = m;
                    }
                    printf("%d\n",num[l-1].first);
                    last = num[l-1].first;
                }
                return 0;
            }
            posted on 2012-06-20 16:44 西月弦 閱讀(1239) 評論(5)  編輯 收藏 引用 所屬分類: 解題報告

            FeedBack:
            # re: bzoj 2653 二分枚舉 + 可持久化線段樹
            2012-07-14 21:36 | 蒟蒻
            CLJ的標程?請問大神在哪找的...  回復  更多評論
              
            # re: bzoj 2653 二分枚舉 + 可持久化線段樹
            2012-07-14 21:40 | 蒟蒻
            還有大神,我是P轉C
            這是什么語法啊
            tree (int _l, int _r, tree *_pl, tree *_pr)
            : l(_l), r(_r), pl (_pl), pr(_pr){
            v = pl->v + pr->v;
            }
            tree (int _l, int _r, int val): l(_l), r(_r){
            提一下名稱...我去百度一下...  回復  更多評論
              
            # re: bzoj 2653 二分枚舉 + 可持久化線段樹
            2012-07-14 22:44 | 西月弦
            @蒟蒻
            這個語法是C++構造函數
            CLJ的題解我的文章里不是有超鏈接么...  回復  更多評論
              
            # re: bzoj 2653 二分枚舉 + 可持久化線段樹
            2012-07-15 19:07 | 蒟蒻
            @西月弦
            只有PDF...沒有標程...  回復  更多評論
              
            # re: bzoj 2653 二分枚舉 + 可持久化線段樹
            2012-07-15 19:12 | 蒟蒻
            找到了...在homework2里...但還是謝謝了...  回復  更多評論
              
            久久无码人妻一区二区三区| 国产99久久久久久免费看| 亚洲Av无码国产情品久久| 99久久香蕉国产线看观香| 伊人久久大香线蕉av不卡| 国产麻豆精品久久一二三| 国产一区二区精品久久凹凸| 欧美成人免费观看久久| 久久久久久a亚洲欧洲aⅴ| 少妇熟女久久综合网色欲| 国产日产久久高清欧美一区| 色偷偷88欧美精品久久久| 国产精品禁18久久久夂久| 久久久久久午夜精品| 青青草国产成人久久91网| 综合人妻久久一区二区精品| 99热热久久这里只有精品68| 亚洲精品蜜桃久久久久久| 久久久精品久久久久特色影视| 国产精品一久久香蕉国产线看观看| 久久国产热这里只有精品| 91精品国产色综合久久| 三级三级久久三级久久| 久久综合五月丁香久久激情| 久久超碰97人人做人人爱| 久久91精品国产91| 久久伊人精品青青草原日本| 免费观看成人久久网免费观看| 国产AⅤ精品一区二区三区久久| 亚洲精品无码久久久久sm| 亚洲精品无码久久久久AV麻豆| 亚洲嫩草影院久久精品| 国产亚洲婷婷香蕉久久精品| 97久久精品国产精品青草| 亚洲精品乱码久久久久久蜜桃不卡 | 日本五月天婷久久网站| 久久久久无码专区亚洲av| 一本大道久久香蕉成人网| 久久久久波多野结衣高潮| 久久久久av无码免费网| 久久精品无码专区免费青青|