BZOJ 3932 [CQOI2015]任务查询系统 (主席树)
题目大意:有n个任务,有起始时间si和结束时间ei,以及该任务重要度pi,求某时刻xi正在进行的任务中,重要度前ki小任务的重要度之和
本以为是一道主席树的水题,可我调了半个多小时才调出来,原来是我新建的主席树根的左右儿子并没继承上个版本,导致某些时刻并没有任何刚开始或刚结束的任务,而在这个时间却找不到这个时刻对应的主席树。
然而我只有80分
看了题解,发现我忽略了一种情况,当很多个任务重要度相同时,可能前ki小个任务并不能把这些任务都取到,特判即可
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 #define N 100100 6 #define ui unsigned int 7 #define il inline 8 #define ll long long 9 #define rint register int 10 using namespace std; 11 12 int n,m,ctt,ma,tot; 13 int root[N]; 14 ll a[N]; 15 struct Seg{int ls,rs;ll sum,sz;}seg[N*50]; 16 vector<ll>S[N]; 17 vector<ll>E[N]; 18 19 int gc(){ 20 int rett=0,fh=1;char p=getchar(); 21 while(p<'0'||p>'9') {if(p=='-')fh=-1;p=getchar();} 22 while(p>='0'&&p<='9') {rett=(rett<<3)+(rett<<1)+p-'0';p=getchar();} 23 return rett*fh; 24 } 25 void build(int l,int r,int rt) 26 { 27 if(l==r) return; 28 int mid=(l+r)>>1; 29 seg[rt].ls=++tot,build(l,mid,seg[rt].ls); 30 seg[rt].rs=++tot,build(mid+1,r,seg[rt].rs); 31 } 32 il void pushup(int rt) 33 {seg[rt].sum=seg[seg[rt].ls].sum+seg[seg[rt].rs].sum; 34 seg[rt].sz=seg[seg[rt].ls].sz+seg[seg[rt].rs].sz;} 35 void update(int x,int l,int r,int rt1,int rt2,ll val) 36 { 37 if(l==r) {seg[rt2].sz+=val,seg[rt2].sum+=val*a[l];return;} 38 int mid=(l+r)>>1; 39 if(x<=mid){ 40 if(!seg[rt2].ls||seg[rt2].ls==seg[rt1].ls){ 41 seg[rt2].ls=++tot,seg[seg[rt2].ls].sz=seg[seg[rt1].ls].sz; 42 seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum; 43 if(!seg[rt2].rs) seg[rt2].rs=seg[rt1].rs; 44 }update(x,l,mid,seg[rt1].ls,seg[rt2].ls,val); 45 }else{ 46 if(!seg[rt2].rs||seg[rt2].rs==seg[rt1].rs){ 47 seg[rt2].rs=++tot,seg[seg[rt2].rs].sz=seg[seg[rt1].rs].sz; 48 seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum; 49 if(!seg[rt2].ls) seg[rt2].ls=seg[rt1].ls; 50 }update(x,mid+1,r,seg[rt1].rs,seg[rt2].rs,val); 51 }pushup(rt2); 52 } 53 ll query(ll w,int l,int r,int rt) 54 { 55 if(l==r){ 56 if(w<seg[rt].sz) return (ll)a[l]*w; 57 else return seg[rt].sum; 58 } 59 int mid=(l+r)>>1; 60 if(seg[seg[rt].ls].sz>=w) return query(w,l,mid,seg[rt].ls); 61 else return seg[seg[rt].ls].sum+query(w-seg[seg[rt].ls].sz,mid+1,r,seg[rt].rs); 62 } 63 64 int main() 65 { 66 scanf("%d%d",&m,&n); 67 int x,y,w;ll z; 68 for(int i=1;i<=m;i++){ 69 x=gc(),y=gc(),z=gc(); 70 a[++ctt]=z,S[x].push_back(z),E[y+1].push_back(z); 71 } 72 sort(a+1,a+ctt+1); 73 ma=unique(a+1,a+ctt+1)-(a+1); 74 a[ma+1]=0x3f3f3f3f; 75 root[0]=++tot,build(1,ma,root[0]); 76 for(int i=1;i<=n;i++){ 77 root[i]=++tot; 78 seg[root[i]].ls=seg[root[i-1]].ls; 79 seg[root[i]].rs=seg[root[i-1]].rs; 80 seg[root[i]].sz=seg[root[i-1]].sz; 81 seg[root[i]].sum=seg[root[i-1]].sum; 82 for(int j=0;j<S[i].size();j++){ 83 int pos=lower_bound(a+1,a+ma+1,S[i][j])-a; 84 update(pos,1,ma,root[i-1],root[i],(ll)1); 85 } 86 for(int j=0;j<E[i].size();j++){ 87 int pos=lower_bound(a+1,a+ma+1,E[i][j])-a; 88 update(pos,1,ma,root[i-1],root[i],(ll)-1); 89 } 90 } 91 ll ans=1; 92 ll s1,s2,s3; 93 for(int i=1;i<=n;i++){ 94 x=gc(),s1=gc(),s2=gc(),s3=gc(); 95 s1=(s1*ans+s2)%s3+1ll; 96 ans=query(s1,1,ma,root[x]); 97 printf("%lld\n",ans); 98 } 99 return 0; 100 }