Bills of Paradise (黑龙江省赛) (值域线段树,线段树的恢复操作其实是On的)

思路:
- 性质一直都是1,N 的满区间
- 前面3个直接利用值域线段树即可
- 后面一个就利用优先队列存被改的数,然后暴力恢复就行, 因为最对被改m次嘛\\

#include<bits/stdc++.h> using namespace std; #define ll long long const ll mod=999999999999; const int N=1e6+5; unsigned long long k1, k2; unsigned long long xorShift128Plus() { unsigned long long k3 = k1, k4 = k2; k1 = k4; k3 ^= k3 << 23; k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26); return k2 + k4; } int n; ll a[N],b[N]; int num[N*4]; ll sum[N*4]; void init(int l,int r,int root,int p){ if(l==r){ sum[root]+=b[l],num[root]++; return ; } int mid=l+r>>1; if(mid>=p) init(l,mid,root<<1,p); if(mid<p) init(mid+1,r,root<<1|1,p); sum[root]=sum[root<<1]+sum[root<<1|1]; num[root]=num[root<<1]+num[root<<1|1]; } priority_queue<ll,vector<ll>,greater<ll> >Q; int q_F(int l,int r,int root,int ql,int qr){ if(!num[root])return -1; if(l==r)return l; int mid=l+r>>1; if(l>=ql&&r<=qr){ if(num[root<<1])return q_F(l,mid,root<<1,ql,qr); else return q_F(mid+1,r,root<<1|1,ql,qr); } //push_down(root); int ans=-1; if(mid>=ql) ans=q_F(l,mid,root<<1,ql,qr); if(mid<qr&&ans==-1) ans=q_F(mid+1,r,root<<1|1,ql,qr); return ans; } int up_D(int l,int r,int root,int ql,int qr){ if(!num[root])return -1; if(l==r){ num[root]--; sum[root]-=b[l]; Q.push(b[l]); return 1; } int mid=l+r>>1; if(l>=ql&&r<=qr){ int ans=-1; if(num[root<<1]){ ans=up_D(l,mid,root<<1,ql,qr); num[root]=num[root<<1]+num[root<<1|1]; sum[root]=sum[root<<1]+sum[root<<1|1]; return ans; } else{ ans=up_D(mid+1,r,root<<1|1,ql,qr); num[root]=num[root<<1]+num[root<<1|1]; sum[root]=sum[root<<1]+sum[root<<1|1]; return ans; } } //push_down(root); int ans=-1; if(mid>=ql) ans=up_D(l,mid,root<<1,ql,qr); if(mid<qr&&ans==-1) ans=up_D(mid+1,r,root<<1|1,ql,qr); num[root]=num[root<<1]+num[root<<1|1]; sum[root]=sum[root<<1]+sum[root<<1|1]; return ans; } ll q_C(int l,int r,int root,int ql,int qr){ if(l>=ql&&r<=qr) return sum[root]; int mid=l+r>>1; ll ans=0; if(mid>=ql) ans=q_C(l,mid,root<<1,ql,qr); if(mid<qr) ans+=q_C(mid+1,r,root<<1|1,ql,qr); return ans; } char s[2]; const ll inf=1e12; void gen() { scanf("%d %llu %llu", &n, &k1, &k2); for (int i = 1; i <= n; i++) { a[i] = xorShift128Plus() %mod + 1; b[i]=a[i]; } sort(b+1,b+1+n); int all=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+1+all,a[i])-b; init(1,all,1,a[i]); } int q; ll x; scanf("%d",&q); while(q--){ scanf("%s%lld",s,&x); if(s[0]=='F'){ int p=lower_bound(b+1,b+1+all,x)-b; if(p>all){ printf("%lld\n",inf); continue; } int pos=q_F(1,all,1,p,all); if(pos==-1)printf("%lld\n",inf); else printf("%lld\n",b[pos]); } else if(s[0]=='D'){ int p=lower_bound(b+1,b+1+all,x)-b; if(p>all)continue; up_D(1,all,1,p,all); } else if(s[0]=='C'){ int p=upper_bound(b+1,b+1+all,x)-b-1; if(p==0) printf("0\n"); else printf("%lld\n",q_C(1,all,1,1,p)); } else { while(!Q.empty()&&Q.top()<=x){ ll u=Q.top();Q.pop(); int p=lower_bound(b+1,b+1+all,u)-b; init(1,all,1,p); } } } } int main() { gen(); }