BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树
【题目分析】
主席树,维护区间大小以及权值之和。
但是细节确实要琢磨很久,WA了几次。
【代码】
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std; #define maxn 300005 #define mlog 40 #define inf (0x3f3f3f3f) #define ll long long ll read() { ll x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } ll llread() { ll x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } ll rt[maxn],ls[maxn*mlog],rs[maxn*mlog],siz[maxn*mlog],tot=0,n,m; struct eve{ll p,opt;}a[maxn]; vector <eve> v[maxn]; ll sum[maxn*mlog]; ll b[maxn],top=0,cnt=0; ll pre=1; /* void ins(ll o1,ll &o2,ll l,ll r,ll x,ll f) { o2=++tot; siz[o2]=siz[o1]+f; sum[o2]=sum[o2]+(ll)b[x]*f; if (l==r) return ; ll mid=(l+r)/2; if (x<=mid) ins(ls[o1],ls[o2],1,mid,x,f),rs[o2]=rs[o1]; else ins(rs[o1],rs[o2],mid+1,r,x,f),ls[o2]=ls[o1]; // sum[o2]=sum[ls[o1]]+sum[ls[o2]]; } */ ll ins (ll o1,ll l,ll r,ll x,ll f) { ll now=++tot; siz[now]=siz[o1]+f; sum[now]=sum[o1]+b[x]*f; if (l==r) return now; ll mid=(l+r)/2; if (x<=mid) ls[now]=ins(ls[o1],l,mid,x,f),rs[now]=rs[o1]; else rs[now]=ins(rs[o1],mid+1,r,x,f),ls[now]=ls[o1]; return now; } ll query(ll o,ll l,ll r,ll x) { if (x>=siz[o]) return sum[o]; if (l==r) return min(x,siz[o])*b[l]; ll tmp=siz[ls[o]]; if (tmp>=x) return query(ls[o],l,(l+r)/2,x); else return sum[ls[o]]+query(rs[o],(l+r)/2+1,r,x-tmp); } int main() { n=read();m=read(); for (ll i=1;i<=n;++i) { ll x=read(),y=read(),z=read(); if (x<=m) { a[++cnt].p=z; a[cnt].opt=1; v[x].push_back(a[cnt]); } if (y+1<=m) { a[++cnt].p=z; a[cnt].opt=-1; v[y+1].push_back(a[cnt]); } b[++top]=z; } sort(b+1,b+top+1); top=unique(b+1,b+top+1)-b-1; for (ll i=1;i<=m;++i) { rt[i]=rt[i-1]; for (ll j=0;j<v[i].size();++j) rt[i]=ins(rt[i],1,top,lower_bound(b+1,b+top+1,v[i][j].p)-b,v[i][j].opt); } for (ll i=1;i<=m;++i) { ll k,x,a,b,c; x=llread();a=llread();b=llread();c=llread(); k=1+(a*pre+b)%c; // if (i==m) k++; printf("%lld\n",pre=query(rt[x],1,top,k)); } }