第15届黑龙江省赛 B. Bills of Paradise

题意:维护数列,四种操作

  1. 查询x的lower_bound
  2. 删去x的lower_bound
  3. 查询小于等于x的sum
  4. 恢复所有小于等于x的2操作

权值线段树维护,需要记录区间最大值和sum;

对于操作1和2,线段树二分

操作3直接查询区间和

操作4考虑均摊,把所有2操作放到priority_queue里,暴力插回去即可

复杂度(O(nlog^2n))

不做离散化会爆空间

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 5000006;
typedef unsigned long long ull;
typedef long long ll;

int rd(){
	int ret=0,f=1;char c;
	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
	return ret*f;
}

ull k1,k2;

ull xorshift(){
	ull k3=k1,k4=k2;	
	k1=k4;
	k3^=k3<<23;
	k2=k3^k4^(k3>>17)^(k4>>26);
	return k2+k4;
}

int n;
ull a[1000001];
ull sava[1000001],aa[1000001];

void gen(){
	scanf("%d%llu%llu",&n,&k1,&k2);
	for(int i=1;i<=n;i++){
		sava[i]=a[i]=xorshift()%999999999999 + 1;
	}
}

const ull INF = 1000000000000ull;
priority_queue<ull> Q;

int rt;
int ch[MAXN][2];
ull sum[MAXN];
ull mxx[MAXN];
map<ull,ull> mp,mp2;
int newnode(){
	static int tot=0;
	return ++tot;	
}
void pushup(int cur){
	sum[cur]=0;
	mxx[cur]=0;
	if(ch[cur][0]) mxx[cur]=max(mxx[cur],mxx[ch[cur][0]]);
	if(ch[cur][1]) mxx[cur]=max(mxx[cur],mxx[ch[cur][1]]);
	if(ch[cur][0]) sum[cur]+=sum[ch[cur][0]];
	if(ch[cur][1]) sum[cur]+=sum[ch[cur][1]];	
}
void insert(int &cur,ull l,ull r,ull w){
	if(!cur) cur=newnode();
	if(l==r){
		mxx[cur]=w;
		sum[cur]=sava[w];
		return;
	}
	ull mid=(l+r)>>1;
	if(w<=mid) insert(ch[cur][0],l,mid,w);
	else insert(ch[cur][1],mid+1,r,w);
	pushup(cur);
}

void del(int cur,ull l,ull r,ull w){
	if(l==r){
		mxx[cur]=0;
		sum[cur]=0;
		return;
	}
	ull mid=(l+r)>>1;
	if(w<=mid) del(ch[cur][0],l,mid,w);
	else del(ch[cur][1],mid+1,r,w);
	pushup(cur);
}
	
ull fnd(int cur,ull l,ull r,ull w){
	if(l==r){
		return l;	
	}
	ull mid=(l+r)>>1;
	if(ch[cur][0]&&mxx[ch[cur][0]]>=w) return fnd(ch[cur][0],l,mid,w);
	else return fnd(ch[cur][1],mid+1,r,w);
}
ull query_sum(int cur,ull l,ull r,ull w){
	if(r<=w){
		return sum[cur];	
	}
	ull mid=(l+r)/2;
	ull ret=0;
	if(ch[cur][0]) ret+=query_sum(ch[cur][0],l,mid,w);
	if(mid<w&&ch[cur][1]) ret+=query_sum(ch[cur][1],mid+1,r,w);
	return ret;
}

int main(){
	gen();
	sort(sava+1,sava+1+n);
	int newnum=unique(sava+1,sava+1+n)-sava-1;
	for(int i=1;i<=n;i++){
		aa[i]=lower_bound(sava+1,sava+1+newnum,a[i])-sava;
		mp[aa[i]]=a[i];
		mp2[a[i]]=aa[i];
	}
	int m=rd();
	ull mx=newnum+1;
	sava[newnum+1]=1e12;
	insert(rt,1,mx,newnum+1);
	for(int i=1;i<=n;i++){
		insert(rt,1,mx,aa[i]);
	}	
	for(int i=1;i<=m;i++){
		char op[10];
		ull x;
		scanf("%s%llu",op,&x);
		if(op[0]=='F'){
			ull tt=lower_bound(sava+1,sava+1+newnum,x)-sava;
			printf("%llu
",sava[fnd(rt,1,mx,tt)]);
		}else if(op[0]=='D'){
			ull tt=lower_bound(sava+1,sava+1+newnum,x)-sava;
			ull tmp=fnd(rt,1,mx,tt);
			del(rt,1,mx,tmp);
			Q.push(-tmp);
		}else if(op[0]=='C'){
			ull tt=lower_bound(sava+1,sava+1+newnum,x)-sava;
			while(tt&&sava[tt]>x) tt--;
			printf("%llu
",query_sum(rt,1,mx,tt));
		}else{
			while(!Q.empty()){
				if(sava[-Q.top()]>x) break;
				insert(rt,1,mx,-Q.top());
				Q.pop();	
			}
		}
	}
	return 0;
}

本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/15369470.html

原文地址:https://www.cnblogs.com/ghostcai/p/15369470.html