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

题目
题解(D题)
数据结构题虽然难写,但是没什么好说的,具体看代码吧

Code

s w p swp 是用来排序的, t o t tot 是用来统计答案的
t r i e trie 树内存要额外* 30 30

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200002;
int sz[N*30],t[N*30][30],c[N*30][2],tot,l,r,cnt,sum[N][30],n,i,num,tim,swp,a[N],m,op;
inline char gc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
	int x=0,fl=1;char ch=gc();
	for(;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
	for(;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
	return x*fl;
}
inline void wri(ll a){if(a<0)a=-a,putchar('-');if(a>=10)wri(a/10);putchar(a%10|48);}
inline void wln(ll a){wri(a),puts("");}
void ins(int x){
	num++;int p=0;
	for (int i=29;~i;i--){
		if (!c[p][(x>>i)&1]) c[p][(x>>i)&1]=++tim;
		p=c[p][(x>>i)&1],sz[p]++;
		for (int j=0;j<30;j++) t[p][j]+=(x>>j)&1;
	}
}
ll find(int k){
	int p=0;ll res=0;
	for (int i=29;~i;i--){
		if (!k) return res;
		int q=c[p][(swp>>i)&1];
		if (k<sz[q]) p=q;
		else{
			k-=sz[q];
			for (int j=0;j<30;j++)
				if ((tot>>j)&1) res+=(ll)(sz[q]-t[q][j])<<j;
				else res+=(ll)t[q][j]<<j;
			p=c[p][((swp>>i)&1)^1];
		}
	}
	for (int i=0;i<30;i++)
		if (((tot>>i)&1)^(t[p][i]>0)) res+=(ll)k<<i;
	return res;
}
ll query(int x){
	if (x<=num) return find(x);
	ll res=find(num);x-=num;
	for (int i=0;i<30;i++)
		if ((tot>>i)&1) res+=(ll)(x-sum[x][i])<<i;
		else res+=(ll)sum[x][i]<<i;
	return res;
}
void push(int x){
	a[++cnt]=x;
	for (int i=0;i<30;i++) sum[cnt][i]=sum[cnt-1][i]+((x>>i)&1);
}
void rebuild(){
	while (cnt) ins(a[cnt--]);
	swp=tot;
}
int main(){
	n=rd();
	for (i=1;i<=n;i++) push(rd());
	for (m=rd();m--;){
		op=rd();
		if (op==1) push(rd()^tot);
		if (op==2) l=rd(),r=rd(),wln(query(r)-query(l-1));
		if (op==3) tot^=rd();
		if (op==4) rebuild();
	}
}

猜你喜欢

转载自blog.csdn.net/xumingyang0/article/details/88546089
今日推荐