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
Codeforces 242E. XOR on Segment (二维线段树 lazy操作 xor)
E. Delete a Segment(删除一个区间,让并区间最多)
Codeforces Round #340 (Div. 2) E. XOR and Favorite Number 莫队算法 + 异或和前缀和的巧妙