rt 本来在做TJOI开关 想着双倍经验 结果爆炸
#include<bits/stdc++.h>
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
using namespace std;
const int mxn=1e6+1;
int light[mxn<<2];
bool lazy_tag[mxn<<2];
inline void init(int root,int start,int end)
{
if(start==end)
{
char a;
cin>>a;
light[root]=a-48;
return;
}
int mid=(start+end)>>1;
init(lc(root),start,mid);
init(rc(root),mid+1,end);
light[root]=light[lc(root)]+light[rc(root)];
}
inline void pushdown(int root,int left_range,int right_range)
{
int len=right_range-left_range+1;
if(lazy_tag[root])
{
lazy_tag[lc(root)]^=1;
lazy_tag[rc(root)]^=1;
int mid=(left_range+right_range)>>1;
light[lc(root)]=(len-(len>>1))-light[lc(root)];
light[rc(root)]=(len>>1)-light[rc(root)];
lazy_tag[root]=0;
}
return;
}
inline void modify(int root,int left_range,int right_range,int start,int end)
{
if(start<=left_range && right_range<=end)
{
light[root]=(right_range-left_range+1)-light[root];
lazy_tag[root]^=1;
return;
}
pushdown(root,start,end);
int mid=(left_range+right_range)>>1;
if(start<=mid) modify(lc(root),left_range,mid,start,end);
if(mid<end) modify(rc(root),mid+1,right_range,start,end);
light[root]=light[lc(root)]+light[rc(root)];
}
inline long long query(int root,int left_range,int right_range,int start,int end)
{
if(start<=left_range && right_range<=end)
return light[root];
pushdown(root,left_range,right_range);
long long a=0,b=0,mid=(left_range+right_range)>>1;
if(start<=mid) a=query(lc(root),left_range,mid,start,end);
if(mid<end) b=query(rc(root),mid+1,right_range,start,end);
return a+b;
}
int main(){
ios::sync_with_stdio(0);
long long n,m,left_range,right_range;
cin>>n>>m;
init(1,1,n);
for(long long i=1;i<=m;i++)
{
bool op;
cin>>op>>left_range>>right_range;
if(op==0)
modify(1,1,n,left_range,right_range);
else
cout<<query(1,1,n,left_range,right_range)<<endl;
}
return 0;
}