题目描述 Description

    YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)

输入描述 Input Description
第 1 行: 用空格隔开的两个整数N和M
第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y 
输出描述 Output Description

第 1..询问总次数 行:对于每一次询问,输出询问的结果

样例输入 Sample Input

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

样例输出 Sample Output
1
2
 
数据范围及提示 Data Size & Hint

一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):

XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4

 

 
题意:中文题意
 
题解:裸的线段树  区间更新 区间查询求和   如果直接更新到叶子节点 线段树就会退化
 lazy 延迟标记  因为只有开灯与关灯两种状态 所以可以%2处理 将累计起来的add  %2处理
只有当add%2==1时间  才需要向下延迟 并更新下一层的add
 
 
卡这里卡了很久ORZZZZ
  1 //code by  drizzle
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<algorithm>
  6 #include<vector>
  7 #define ll __int64
  8 #define PI acos(-1.0)
  9 #define mod 1000000007
 10 using namespace std;
 11 int n,m;
 12 int flag,x,y;
 13 struct node
 14 {
 15     int l;
 16     int r;
 17     int add;
 18     int sum;
 19 }tree[400005];
 20 void buildtree(int root,int left,int right)
 21 {
 22     tree[root].l=left;
 23     tree[root].r=right;
 24     tree[root].add=0;
 25     if(left==right)
 26     {
 27         tree[root].sum=0;
 28         return;
 29     }
 30     int mid=(left+right)>>1;
 31     buildtree(root<<1,left,mid);
 32     buildtree(root<<1|1,mid+1,right);
 33     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
 34 }
 35 void pushdown(int root,int m)
 36 {
 37     tree[root<<1].add++;
 38     tree[root<<1].add=tree[root<<1].add%2;
 39     tree[root<<1|1].add++;
 40     tree[root<<1|1].add=tree[root<<1|1].add%2;
 41     tree[root<<1].sum=(m-(m>>1))-tree[root<<1].sum;
 42     tree[root<<1|1].sum=(m>>1)-tree[root<<1|1].sum;
 43     tree[root].add=0;
 44 }
 45 void updata(int c,int left,int right,int root)
 46 {
 47     if(tree[root].l==left&&tree[root].r==right)
 48     {
 49          tree[root].add++;
 50          tree[root].add=tree[root].add%2;
 51          tree[root].sum=right-left+1-tree[root].sum;
 52         return ;
 53     }
 54     if(tree[root].l==tree[root].r)
 55         return ;
 56     if(tree[root].add)
 57         pushdown(root,tree[root].r-tree[root].l+1);
 58     int mid=(tree[root].l+tree[root].r)>>1;
 59     if(right<=mid)
 60     updata(c,left,right,root<<1);
 61     else
 62     {
 63         if(left>mid)
 64             updata(c,left,right,root<<1|1);
 65         else
 66         {
 67             updata(c,left,mid,root<<1);
 68             updata(c,mid+1,right,root<<1|1);
 69         }
 70     }
 71     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
 72 }
 73 int query(int root ,int left,int right)
 74 {
 75     if(tree[root].l==left&&tree[root].r==right)
 76     {
 77         return tree[root].sum;
 78     }
 79     if(tree[root].add)
 80         pushdown(root,tree[root].r-tree[root].l+1);
 81     int mid=(tree[root].l+tree[root].r)>>1;
 82     if(right<=mid)
 83          return query(root<<1,left,right);
 84     else
 85     {
 86         if(left>mid)
 87          return query(root<<1|1,left,right);
 88         else
 89            return (query(root<<1,left,mid)+query(root<<1|1,mid+1,right));
 90     }
 91 }
 92 int main()
 93 {
 94     while(scanf("%d %d",&n,&m)!=EOF)
 95     {
 96         buildtree(1,1,n);
 97         for(int i=1;i<=m;i++)
 98         {
 99             scanf("%d %d %d",&flag,&x,&y);
100             if(flag==0)
101             {
102                 updata(1,x,y,1);
103             }
104             else
105             {
106                 printf("%d\n",query(1,x,y));
107             }
108         }
109     }
110     return 0;
111 }