开关灯
lites
[问题描述]
Farmer John尝试通过和奶牛们玩益智玩具来保持奶牛们思维敏
捷。 其中一个大型玩具是牛栏中的灯, N (2 <=N <=100,000) 头
奶牛被连续的编号为1..N,每头牛都站在一个彩色的灯下面。
刚到傍晚的时候, 所有的灯都是关闭的。 奶牛们通过N个按钮来
控制灯的开关, 按第i个按钮可以改变第i个灯的状态。奶牛们执行M
(1 <=M <=100,000)条指令,指令共有两种,第1种指令用0表示,指
令里包含两个数字S_i和E_i (1 <=S_i <=E_i <=N),表示奶牛们
只需要把从S_i到E_i之间的按钮都按一次就可以完成这个指令。第2种
指令用1表示,同样包含两个数字S_i和E_i (1 <=S_i <=E_i <=
N), 不过这种指令是询问从S_i到E_i之间有多少灯是亮着的。请你帮
助奶牛们得到正确的答案。
[输⼊]
第 1 行:用空格隔开的两个整数N和M。
第 2..M+1 行:每行表示一个操作, 有三个用空格分开的整数: 指令,
S_i 和 E_i。
[输出]
第 1..询问的次数行:对于每一次询问,输出询问的结果。
样例输⼊ 样例输出
4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4
1
2
lazy操作模板:
#include<stdio.h>
#include<iostream>
#define goback(x) ((x==true)?(false):(true))
using namespace std;
const int MAX_N = 100050;
const int root = 1;
struct node
{
int ID;
int L,R;
int Lid,Rid;
bool fback;
int sum ;
};
struct node T[MAX_N*2];
int N,M;
int times = 0;
void Build(int l,int r)
{
if (l>r) return ;
if (l==r)
{
times++;
T[times]=(struct node){times,l,r,-1,-1,false,0};
return ;
}
int mid=(l+r)/2;
int now=++times;
int lid=times+1;
Build(l,mid);
int rid=times+1;
Build(mid+1,r);
T[now]=(struct node){now,l,r,lid,rid,false,0};
}
void init()
{
scanf("%d %d",&N,&M);
Build(1,N);
}
int solve(int t,int s,int e)
{
int l=T[t].L;
int r=T[t].R;
int mid=(l+r)/2;
if (s>r) return 0;
if (e<l) return 0;
if (t==-1) return 0;
if (s<=l&&e>=r) return T[t].sum;
if (T[t].fback)
{
T[t].fback=goback(T[t].fback);
T[T[t].Lid].fback=goback(T[T[t].Lid].fback);
T[T[t].Rid].fback=goback(T[T[t].Rid].fback);
T[T[t].Lid].sum=T[T[t].Lid].R-T[T[t].Lid].L+1-T[T[t].Lid].sum;
T[T[t].Rid].sum=T[T[t].Rid].R-T[T[t].Rid].L+1-T[T[t].Rid].sum;
}
if (e<=mid)
return solve(T[t].Lid,s,e);
else if (s>mid)
return solve(T[t].Rid,s,e);
else return solve(T[t].Lid,s,mid)+solve(T[t].Rid,mid+1,e);
}
int change(int t,int s,int e)
{
int l=T[t].L;
int r=T[t].R;
int mid=(l+r)/2;
if (t==-1) return 0;
if (s>r) return 0;
if (e<l) return 0;
if (s<=l&&e>=r)
{
T[t].fback=goback(T[t].fback);
T[t].sum=T[t].R-T[t].L+1-T[t].sum;
return T[t].sum;
}
if (T[t].fback)
{
T[t].fback=goback(T[t].fback);
T[T[t].Lid].fback=goback(T[T[t].Lid].fback);
T[T[t].Rid].fback=goback(T[T[t].Rid].fback);
T[T[t].Lid].sum=T[T[t].Lid].R-T[T[t].Lid].L+1-T[T[t].Lid].sum;
T[T[t].Rid].sum=T[T[t].Rid].R-T[T[t].Rid].L+1-T[T[t].Rid].sum;
}
if (e<=mid)
change(T[t].Lid,s,e);
else if (s>mid)
change(T[t].Rid,s,e);
else change(T[t].Lid,s,mid),change(T[t].Rid,mid+1,e);
T[t].sum=T[T[t].Lid].sum+T[T[t].Rid].sum;
return T[t].sum;
}
void work_put()
{
int i;
int Q,A,B;
for (i=1;i<=M;i++)
{
scanf("%d %d %d",&Q,&A,&B);
if (Q==0)
change(root,A,B);
if (Q==1)
printf("%d\n",solve(root,A,B));
}
}
int main()
{
freopen("lites.in","r",stdin);
freopen("lites.out","w",stdout);
init();
work_put();
return 0;
}