蒟蒻求助红题
查看原帖
蒟蒻求助红题
87064
ducati楼主2020/9/6 17:15

尽管下面那几行代码特别长,但是,您只需要看第85-97行,第100-102行,第123-128行即可。

#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;
 
int n,q,x,pos,opt,le,ri,k;
int a[100005][31],tree[31][400005],tag[31][400005],p[31],tmp[31];
 
inline void pushup(int t,int rt)
{
	tree[t][rt]=tree[t][2*rt]+tree[t][2*rt+1];
}
 
inline void build_tree(int t,int l,int r,int rt)
{
	if (l==r)
	{
		tree[t][rt]=a[l][t];
		return;
	}
	int mid=(l+r)>>1;
	
	build_tree(t,l,mid,2*rt);
	build_tree(t,mid+1,r,2*rt+1);
	pushup(t,rt);
}
 
inline void f(int t,int l,int r,int rt)
{
	tree[t][rt]=(r-l+1)-tree[t][rt];
	tag[t][rt]=(tag[t][rt]+1)%2;
}
 
inline void pushdown(int t,int l,int r,int rt)
{
	if (tag[t][rt])
	{
		int mid=(l+r)>>1;
		f(t,l,mid,2*rt);
		f(t,mid+1,r,2*rt+1);
	}
	tag[t][rt]=0;
}
 
inline void change(int t,int nl,int nr,int l,int r,int rt)
{
	if (nl<=l&&r<=nr)
	{
		f(t,l,r,rt);
		return;
	}
	pushdown(t,l,r,rt);
	
	int mid=(l+r)>>1;
	if (nl<=mid)  change(t,nl,nr,l,mid,2*rt);
	if (nr>mid)  change(t,nl,nr,mid+1,r,2*rt+1);
	
	pushup(t,rt);
}
 
inline int query(int t,int nl,int nr,int l,int r,int rt)
{
	pushdown(t,l,r,rt);
	
	int mid=(l+r)>>1,tot=0;
	if (nl<=l&&r<=nr)  return tree[t][rt];
	if (nl<=mid)  tot=query(t,nl,nr,l,mid,2*rt);
	if (nr>mid)  tot+=query(t,nl,nr,mid+1,r,2*rt+1);
	return tot;
}
 
inline void init()
{
	p[0]=1;
	for (int i=1;i<=25;i++)  p[i]=(p[i-1]*2);
}
 
inline int segment_query(int le,int ri)
{
	int ans=0; 
	for (int i=1;i<=25;i++)  ans+=p[25-i]*query(i,le,ri,1,n,1);
	return ans;
}
 
inline void segment_change(int le,int ri,int k)
{
	pos=25;	
	while (k)
	{
		tmp[pos]=k%2;
		pos--;
		k/=2;
	}
	for (int i=1;i<=25;i++)
	{
		if (tmp[i])  change(i,le,ri,1,n,1);
	}
}
 
inline void clear()
{
	for (int i=1;i<=30;i++)  tmp[i]=0;
}
 
signed main()
{
	cin>>n;
	init();
	for (int i=1;i<=n;i++)
	{
		cin>>x;
		pos=25;
		
		while (x)
		{
			a[i][pos]=x%2;
			x/=2,pos--;
		}
	}
	for (int i=1;i<=25;i++)  build_tree(i,1,n,1);
 
	cin>>q;
	while (q--)
	{
		clear();
		cin>>opt>>le>>ri;
		if (opt==1)  cout<<segment_query(le,ri)<<endl;
		else cin>>k,segment_change(le,ri,k);
	}
	return 0;
}
2020/9/6 17:15
加载中...