现在的位置: 首页 > 综合 > 正文

Codeforces Round #149 (Div. 2) E – XOR on Segment

2019年02月10日 ⁄ 综合 ⁄ 共 1323字 ⁄ 字号 评论关闭

二维线段树,卡了一下午,求和时,sum会溢出,所以类型用__int64


#include<cstdio>
using namespace std;

const int MAXN = 811111;
struct tree{

	int cnt[MAXN], lazy[MAXN];
	inline void rev(int id, int l, int r)
	{
		cnt[id] = r-l+1-cnt[id];
		lazy[id]^=1;
	}
	void update(int id, int l, int r, int st, int en)
	{
		if(l==st&&r==en)
		{
			rev(id,l,r);
			return ;
		}
		int mid = (st+en)>>1;
		if(lazy[id])
		{
			lazy[id]=0;
			rev(id<<1,st,mid);
			rev(id<<1|1, mid+1,en);
		}
		if(r<=mid) update(id<<1,l,r,st,mid);
		else if(l>mid) update(id<<1|1,l,r,mid+1,en);
		else 
		{
			update(id<<1,l,mid,st,mid);
			update(id<<1|1,mid+1,r,mid+1,en);
		}
		cnt[id] = cnt[id<<1]+cnt[id<<1|1];
	}
	int query(int id, int l, int r, int st, int en)
	{
		if(l==st&&r==en) return cnt[id];
		int mid = (st+en)>>1;
		if(lazy[id])
		{
			lazy[id]=0;
			rev(id<<1,st,mid);
			rev(id<<1|1, mid+1,en);
		}
		int ans =0 ;
		if(r<=mid) ans = query(id<<1,l,r,st,mid);
		else if(l>mid) ans = query(id<<1|1,l,r,mid+1,en);
		else {
			ans = query(id<<1,l,mid,st,mid)+query(id<<1|1,mid+1,r,mid+1,en);
		}
		cnt[id]=cnt[id<<1]+cnt[id<<1|1];
		return ans;
	}
}T[20];
int main()
{
	int n;scanf("%d",&n);
	for(int i=1; i<=n;i++)
	{
		int x;scanf("%d",&x);
		for(int j=0; j<20; ++j)
			if(x&(1<<j))T[j].update(1,i,i,1,n);
	}
	int m;scanf("%d",&m);
	while(m--)
	{
		int comm;scanf("%d",&comm);
		if(comm==1)
		{
			int l, r;scanf("%d%d",&l,&r);
			__int64 sum = (__int64) 0;
			for(int i=0; i<20; i++) sum+=(__int64)(1<<i)*T[i].query(1,l,r,1,n);
			printf("%I64d\n",sum);
		}
		else
		{
			int l,r,x;scanf("%d%d%d",&l,&r,&x);
			for(int i=0; i<20; ++i) if(x&(1<<i)) T[i].update(1,l,r,1,n);
		}
	}
	
	
	return 0;
}

抱歉!评论已关闭.