BZOJ2161: 布娃娃 整体二分

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector> 
#define maxn 500005
#define setIO(s) freopen(s".in","r",stdin)
#define mod 19921228
#define ll long long 
using namespace std;
vector <int> G[maxn]; 
struct Node{
    int l,r,c,p; 
}node[maxn],arr[maxn]; 
int n;   
namespace DATA_Maker{
    int C[maxn],L[maxn],R[maxn],P[maxn];
    void make(int *a){
        int pa,pf,pm,pp; 
        scanf("%d%d%d%d",&pa,&pf,&pm,&pp);
        a[1] = pf % pm;
        for(int i = 2;i <= n; ++i) a[i]=((long long)a[i-1]*pp+pa+i)%pm; 
    }
    int main(){ 
        scanf("%d",&n);
        make(P); for(int i=1;i<=n;++i) node[i].p=P[i];
        make(C); for(int i=1;i<=n;++i) node[i].c=C[i];
        make(L); for(int i=1;i<=n;++i) node[i].l=L[i]; 
        make(R); for(int i=1;i<=n;++i) node[i].r=R[i]; 
    }
};     
namespace Solve{
    int hh[maxn],que[maxn],cc[maxn],cur[maxn],answer[maxn],tl[maxn],tr[maxn]; 
    struct Array{
        int A[maxn];
        int lowbit(int t){ return t&(-t); }
        void update(int pos,int delta){ while(pos<maxn) A[pos]+=delta,pos+=lowbit(pos);  }
        void add(int l,int r,int k){ update(l,k),update(r+1,-k); }
        int query(int x){ if(!x) return 0; int sum=0; while(x>0) sum+=A[x],x-=lowbit(x); return sum;  }
    }T;                                        
    void solve(int x,int y,int l,int r){
        if(l>r||x>y) return;                          
        if(l==r){  
            for(int i=x;i<=y;++i) answer[que[i]]=cc[l]; 
            return; 
        }
        int mid=(l+r)>>1,p=0,q=0,kk=x-1;
        for(int i=mid+1;i<=r;++i) 
            for(int j=0;j<G[i].size();++j)  T.add(node[G[i][j]].l,node[G[i][j]].r,1); 
        for(int i=x;i<=y;++i) {
            int delta=cur[que[i]]+T.query(node[que[i]].p);   
            if(delta>=que[i]) tr[++q]=que[i];           
            else tl[++p]=que[i],cur[que[i]]=delta;   
        }
        for(int i=mid+1;i<=r;++i) 
            for(int j=0;j<G[i].size();++j) T.add(node[G[i][j]].l,node[G[i][j]].r,-1);
        for(int i=1;i<=p;++i) que[++kk]=tl[i];
        for(int i=1;i<=q;++i) que[++kk]=tr[i]; 
        solve(x,x+p-1,l,mid),solve(y-q+1,y,mid+1,r); 
    }
    int main()         
    {
        //=======================================离散化
        int cnt=0,mx=0; 
        for(int i=1;i<=n;++i)
        {
            hh[++cnt]=node[i].l;
            hh[++cnt]=node[i].r;
            hh[++cnt]=node[i].p; 
        }
        sort(hh+1,hh+1+cnt); 
        for(int i=1;i<=n;++i) 
        { 
            node[i].p=lower_bound(hh+1,hh+1+cnt,node[i].p)-hh;
            node[i].l=lower_bound(hh+1,hh+1+cnt,node[i].l)-hh;
            node[i].r=lower_bound(hh+1,hh+1+cnt,node[i].r)-hh; 
            if(node[i].l>node[i].r)swap(node[i].l,node[i].r); 
        }  
        for(int i=1;i<=n;++i) cc[i]=node[i].c;
        sort(cc+1,cc+1+n); 
        for(int i=1;i<=n;++i) node[i].c=lower_bound(cc+1,cc+1+n,node[i].c)-cc; 
        //========================================离散完毕
        for(int i=1;i<=n;++i) G[node[i].c].push_back(i),mx=max(mx,node[i].c); 
        for(int i=1;i<=n;++i) que[i]=i; 
        solve(1,n,0,mx); 
        long long tmp=0; 
        for(int i=1;i<=n;++i) tmp+=answer[i],tmp%=mod; 
        printf("%lld",tmp);  
    }
}; 
int main(){
    //setIO("input"); 
    DATA_Maker::main(); 
    Solve::main(); 
    return 0; 
}

  

posted @ 2019-02-13 13:10  EM-LGH  阅读(207)  评论(0编辑  收藏  举报