E. XOR on Segment(区间异或)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E. XOR on Segment(区间异或)相关的知识,希望对你有一定的参考价值。

E. XOR on Segment(区间异或)

区间异或,区间求和模板题。

考虑按位计算,因为每位在异或时是独立的,所以每个结点开长度为 20 20 20的数组,表示每位1的个数。

然后就线段树模板了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
//if have char input #define should cancel
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline T& read(T& r) {
    r = 0; bool w = 0; char ch = getchar();
    while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    return r = w ? -r : r;
}
struct node{
	int l,r,lz,b[20];
}a[N<<2];
#define il inline
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
il void re(int x){
	for(int i=0;i<20;i++)
		a[x].b[i]=a[lx].b[i]+a[rx].b[i];
}
il void pd(int x){
	if(a[x].lz){
		int c=a[x].lz;
		a[lx].lz^=c,a[rx].lz^=c;
		for(int i=0;c;i++,c>>=1)
			if(c&1){
				a[lx].b[i]=len(lx)-a[lx].b[i];
				a[rx].b[i]=len(rx)-a[rx].b[i];
			}
		a[x].lz=0;
	}
}
void bud(int x,int l,int r){
	a[x].l=l,a[x].r=r;
	if(l==r){
		int c;read(c);
		for(int i=0;c;i++,c>>=1)
			if(c&1) a[x].b[i]++;
		return;
	}
	int m=l+r>>1;
	bud(lx,l,m),bud(rx,m+1,r);
	re(x);
}
void upd(int x,int l,int r,int v){
	if(a[x].l>=l&&a[x].r<=r){
		int c=v;
		for(int i=0;c;i++,c>>=1)
			if(c&1) a[x].b[i]=len(x)-a[x].b[i];
		a[x].lz^=v;return;
	}
	pd(x);
	int m=a[x].l+a[x].r>>1;
	if(l<=m) upd(lx,l,r,v);
	if(r>m) upd(rx,l,r,v);
	re(x);
}
ll que(int x,int l,int r){
	if(a[x].l>=l&&a[x].r<=r){
		ll s=0;
		for(int i=0;i<20;i++)
			s+=1LL*a[x].b[i]*(1<<i);
		return s;
	}
	pd(x);
	ll s=0;
	int m=a[x].l+a[x].r>>1;
	if(l<=m) s+=que(lx,l,r);
	if(r>m) s+=que(rx,l,r);
	return s;
}
int n,m;
int main(){
	read(n);bud(1,1,n);
	read(m);while(m--){
		int op,l,r,x;read(op),read(l),read(r);
		if(op==1)  printf("%I64d\\n",que(1,l,r));
		else read(x),upd(1,l,r,x);
	}
	return 0;
}

以上是关于E. XOR on Segment(区间异或)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 617 E. XOR and Favorite Number

E. XOR and Favorite Number

Codeforces 242E. XOR on Segment (二维线段树 lazy操作 xor)

E. Delete a Segment(删除一个区间,让并区间最多)

位运算 异或51nod区间xor

Codeforces Round #340 (Div. 2) E. XOR and Favorite Number 莫队算法 + 异或和前缀和的巧妙