[解题记录] P2574 XOR的艺术
P2574 XOR的艺术
题意简述
- 异或一个区间 \([a,b]\)
- 指定一个区间 \([a,b]\),求区间里 \(1\) 的个数
解题思路
异或和乘法加法一样满足结合律,所以可以用线段树去维护
对于操作 \(2\) ,我们可以很简单地想到用区间和去维护
那么对于操作一,我们可以这样想,一个区间里,因为只有 \(1\) 和 \(0\) ,所以用区间长度减去当前 \(1\) 的个数
就是 \(0\) 的个数(即异或后 \(1\) 的个数),因为这是区间修改,我们需要运用到懒标记,并且由于:
\(0\)^\(1= 1\)
\(1\)^\(1=0\)
也就是说,异或两次就等于不异或,所以如果懒标记为 \(0\),就不用修改了
\(Code\)
#include <bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
#define int long long
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*f;
}
const int N=8e5+10;
struct node{
    int dat,lazy;
}tree[N];
int m,mod,tot,a[N],n;
char s[N];
void pushdown(int p,int l,int r){
    if(!tree[p].lazy) return;
    int mid=(l+r)>>1;
    tree[ls].lazy^=1;
    tree[rs].lazy^=1;
    tree[ls].dat=(mid-l+1)-tree[ls].dat;
    tree[rs].dat=(r-mid)-tree[rs].dat;
    tree[p].lazy=0;
    return;
}
void upd(int p,int l,int r,int x,int y){
    if(x<=l&&y>=r){
	tree[p].dat=(r-l+1)-tree[p].dat;
	tree[p].lazy^=1;
	return;
    }
    int mid=(l+r)>>1;
    pushdown(p,l,r);
    if(x<=mid) upd(ls,l,mid,x,y);
    if(y>mid) upd(rs,mid+1,r,x,y);
    tree[p].dat=tree[ls].dat+tree[rs].dat;
}
void build(int p,int l,int r){
    if(l==r){tree[p].dat=a[l];return;}
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    tree[p].dat=tree[ls].dat+tree[rs].dat;
}
int query(int p,int l,int r,int x,int y){
    int res=0;
    if(x<=l&&y>=r){
	res+=tree[p].dat;
	return res;
    }
    int mid=(l+r)>>1;
    pushdown(p,l,r);
    if(x<=mid) res+=query(ls,l,mid,x,y);
    if(y>mid) res+=query(rs,mid+1,r,x,y);
    return res;
}
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;++i) cin>>s[i];
    for(int i=1;i<=n;++i) a[i]=s[i]-'0';
    build(1,1,n);
    for(int i=1;i<=m;++i){
	int op,l,r;
	scanf("%lld%lld%lld",&op,&l,&r);
	if(!op) upd(1,1,n,l,r);
	else cout<<query(1,1,n,l,r)<<endl;
    }
    return 0;
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号