zoukankan      html  css  js  c++  java
  • bzoj 2653 middle(陈立杰) 二分枚举 + 可持久化线段树

    http://www.lydsy.com/JudgeOnline/problem.php?id=2653

    题目描述:
       给长度为20000的序列。求左端点在[a,b]和右端点在[c,d]中所有的子序列,最大的中位数。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    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){
            if(L <= l && R >= r){
                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 ;
        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=1;i<n;i++){
            root[i] = root[i-1] -> change(num[i-1].second, -1);
        }
        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;
                if(chk(m,q[0],q[1],q[2],q[3])) l = m+1;
                else r = m;
            }
            printf("%d
    ",num[l-1].first);
            last = num[l-1].first;
        }
        return 0;
    }
    

      

  • 相关阅读:
    HDOJ_1010 Tempter of the Bone
    矩阵旋转
    HDU 2544 最短路 http://acm.hdu.edu.cn/showproblem.php?pid=2544
    题目连接:http://acm.zznu.edu.cn/problem.php?id=1329
    队列/优先队列(代码简单模式)
    虚拟方法调用
    Vim中分屏(整理)
    Java Web设计模式之依赖倒换原则
    Java Web 设计模式之开闭原则
    Java 2+2=5
  • 原文地址:https://www.cnblogs.com/tobec/p/3266411.html
Copyright © 2011-2022 走看看