萌新0pts求助
查看原帖
萌新0pts求助
195331
Mine_KingCattleya楼主2021/8/29 22:26

Rt,用的是题解里的做法,就是一个 trie 和一个按位前缀和分别维护有序段和无序段,但是仅仅过了样例,求大佬帮忙调一下

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,Xor,triexor;
int node,trie[6000005][2],num[6000005],val[6000005][32];
int cnt,a[200005],sum[200005][30];
void insert_end(int x)
{
	cnt++;
	a[cnt]=x;
	for(int i=0;i<=29;i++) sum[cnt][i]=sum[cnt-1][i]+((x>>i)&1);
	return ;
}
void insert_trie(int x)
{
	int rt=0;
	num[0]++;
	for(int i=29;i>=0;i--)
	{
		int now=(x>>i)&1;
		if(!trie[rt][now]) trie[rt][now]=++node;
		rt=trie[rt][now];
		for(int j=29;j>=0;j--)
			val[rt][j]+=(x>>j)&1;
		num[rt]++;
	}
	return ;
}
long long query_trie(int x)
{
	if(x==0) return 0;
	int rt=0,valx=0;
	long long res=0;
	for(int i=29;i>=0;i--)
	{
		int b=(Xor>>i)&1;
		if(x<=num[trie[rt][b]]) rt=trie[rt][b],valx+=b<<i;
		else
		{
			x-=num[trie[rt][b]];
			for(int j=29;j>=0;j--)
				if((triexor>>j)&1)
					res+=(long long)(num[trie[rt][b]]-val[trie[rt][b]][j])<<j;
				else res+=(long long)val[trie[rt][b]][j]<<j;
			rt=trie[rt][b^1];
			valx+=(b^1)<<i;
		}
	}
	return res+(valx^triexor)*x;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		insert_end(x);
	}
	scanf("%d",&m);
	while(m--)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int x;
			scanf("%d",&x);
			insert_end(x^Xor);
		}
		else if(op==2)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			long long res=0;
			if(l<=num[0]) res=query_trie(min(num[0],r))-query_trie(l-1);
			if(r>num[0])
			{
				int l1=max(1,l-num[0]),r1=r-num[0];
				for(int i=29;i>=0;i--)
				{
					if((Xor>>i)&1)
						res+=(long long)(r1-l1+1-sum[r1][i]+sum[l1-1][i])<<i;
					else res+=(long long)(sum[r1][i]-sum[l1-1][i])<<i;
				}
			}
			printf("%lld\n",res);
		}
		else if(op==3)
		{
			int x;
			scanf("%d",&x);
			Xor^=x;
		}
		else
		{
			for(int i=1;i<=cnt;i++) insert_trie(a[i]);
			cnt=0;triexor=Xor;
		}
	}
	return 0;
}
2021/8/29 22:26
加载中...