15届黑龙江省赛 B. Bills of Paradise —— 线段树
作者:互联网
题意:
题解:
对于前三个都可以用权值线段树,对于R操作,我们可以直接在D操作删除的时候用一个优先队列来存有哪些数被删掉了。时间复杂度可以保证是因为每个数被加进来都需要一次操作,所以不会超过n次操作R。
线段树较为庞大,敲代码时应当更注意细节,例如在D操作的时候,return之前应当push_up
#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();
}
标签:15,int,ll,mid,long,Paradise,return,Bills,root 来源: https://blog.csdn.net/tianyizhicheng/article/details/111159685