「LibreOJ β Round #2」计算几何瞎暴力

https://loj.ac/problem/517

题解

首先我们如果没有排序这个骚操作的话,可以直接记一下各个数位的前缀和,然后异或标记给全局打,查询的时候先把区间信息提取出来然后整体异或就好了。

对于排序,我们考虑对所有排好序的节点建\(trie\)树,这样即使有全局异或标记,我们也可以在\(trie\)树上完成前缀信息的查询。

然后就做完了。

代码

#include<bits/stdc++.h>
#define N 200009
#define ls ch[cnt][0]
#define rs ch[cnt][1]
using namespace std;
typedef long long ll;
const int maxn=30;
int a[N],n,q;
int ch[N*maxn][2],ct[N*maxn][maxn],size[N*maxn],sm[N][maxn];
int tot,rot;
int tag,nowtag;
ll ton[32],nw;
inline ll rd(){
	ll x=0;char c=getchar();bool f=0;
	while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f?-x:x;
}
void ins(int &cnt,int x,int p){
	if(!cnt)cnt=++tot;
	size[cnt]++;
	for(int i=0;i<=29;++i)if((1<<i)&x)ct[cnt][i]++;
	if(p<0)return;
	int o=(x&(1<<p))!=0;
	if(o)ins(rs,x,p-1);
	else ins(ls,x,p-1);
}
inline ll getsum(int now){
	memset(ton,0,sizeof(ton));
	if(now>=nw){
		for(int i=0;i<=29;++i)ton[i]+=sm[now][i];
	}
	else{
		int cnt=rot,siz=now;
		for(int i=29;i>=0;--i){
			int lson=ls,rson=rs;
			if(nowtag&(1<<i))swap(lson,rson);
			if(size[lson]>=siz)cnt=lson;
			else{
				for(int j=0;j<=29;++j)ton[j]+=ct[lson][j];
				siz-=size[lson];
				cnt=rson;
			}
		}
		if(siz){
			for(int i=0;i<=29;++i)ton[i]+=(ct[cnt][i]!=0)*siz;
		}
	}
	ll ans=0;
	for(int i=0;i<=29;++i){
		ll ss;
		if(tag&(1<<i))ss=now-ton[i];else ss=ton[i];
	//	cout<<ss<<" ";
		ans+=ss*(1ll<<i);
	}
	//cout<<"??\n";
	return ans;
}
int main(){
//	freopen("1.txt","r",stdin);
//	freopen("out","w",stdout);
	n=rd();
	nw=1;
	for(int i=1;i<=n;++i){
	  a[i]=rd();
	  for(int j=0;j<=29;++j)sm[i][j]=sm[i-1][j]+((a[i]&(1<<j))!=0);
    }
	q=rd();
	int opt,x,l,r;
	while(q--){
		opt=rd();
		if(opt==1){
			x=rd();x^=tag;
			++n;a[n]=x;
			for(int j=0;j<=29;++j)sm[n][j]=sm[n-1][j]+((a[n]&(1<<j))!=0);
		}
		else if(opt==2){
			l=rd();r=rd();
			printf("%lld\n",getsum(r)-getsum(l-1));
		}
		else if(opt==3)tag^=rd();
		else if(opt==4){
			nowtag=tag;
			while(nw<=n)ins(rot,a[nw],29),nw++;
		}
	}
	return 0;
}

posted @ 2019-06-26 18:33  comld  阅读(255)  评论(0编辑  收藏  举报