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;
}