线段树01区间翻转,挺裸的,就是区间+1%2,然后求和
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=500500;
struct Tree
{
int son[2],bond[2];
int la,asum;
}t[M];
int n,m;
string s;
int num[M],cnt=1,rt=0;
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline void up(int x)
{
int ls=t[x].son[0];
int rs=t[x].son[1];
t[x].asum=t[ls].asum+t[rs].asum;
t[x].bond[0]=t[ls].bond[0];
t[x].bond[1]=t[rs].bond[1];
return ;
}
inline void built(int l,int r,int cur)
{
if (l==r)
{
t[cur].asum=num[l];
t[cur].bond[0]=t[cur].bond[1]=l;
t[cur].son[0]=t[cur].son[1]=-1;
return ;
}
t[cur].son[0]=cnt++;
t[cur].son[1]=cnt++;
int mid=(l+r)>>1;
built(l,mid,t[cur].son[0]);
built(mid+1,r,t[cur].son[1]);
return (void)(up(cur));
}
inline void down(int x)
{
if (t[x].la%2==0) return ;
int ls=t[x].son[0];
int rs=t[x].son[1];
t[ls].asum=(t[ls].bond[1]-t[ls].bond[0]+1-t[ls].asum);
t[rs].asum=(t[rs].bond[1]-t[rs].bond[0]+1-t[rs].asum);
t[ls].la++;t[rs].la++;t[x].la=0;
return ;
}
inline void date(int l,int r,int val,int cur)
{
if (l<=t[cur].bond[0]&&t[cur].bond[1]<=r)
{
t[cur].asum=(t[cur].bond[1]-t[cur].bond[0]+1-t[cur].asum);
return (void)(t[cur].la++);
}
down(cur);
int mid=(t[cur].bond[0]+t[cur].bond[1])>>1;
if (l<=mid) date(l,r,val,t[cur].son[0]);
if (r>mid) date(l,r,val,t[cur].son[1]);
return (void)(up(cur));
}
inline int query(int l,int r,int x)
{
if (l<=t[x].bond[0]&&t[x].bond[1]<=r) return t[x].asum;
down(x);up(x);int tot=0;
int mid=(t[x].bond[0]+t[x].bond[1])>>1;
if (l<=mid) tot+=query(l,r,t[x].son[0]);
if (r>mid) tot+=query(l,r,t[x].son[1]);
return tot;
}
signed main()
{
n=read();m=read();built(1,n,rt);
while (m--)
{
int a=read(),b=read(),c=read();
if (a==0) date(b,c,1,rt);
else cout<<query(b,c,rt)<<endl;
}
return 0;
}