【codevs1690】开关灯 线段树 区间修改+区间求和(标记)

【codevs1690】开关灯

题目描述 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

代码

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <ctime>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <set>
  8 #include <vector>
  9 #include <queue>
 10 #include <typeinfo>
 11 #include <map>
 12 #include <stack>
 13 typedef long long ll;
 14 using namespace std;
 15 inline ll read()
 16 {
 17     ll x=0,f=1;
 18     char ch=getchar();
 19     while(ch<'0'||ch>'9')
 20     {
 21         if(ch=='-')f=-1;
 22         ch=getchar();
 23     }
 24     while(ch>='0'&&ch<='9')
 25     {
 26         x=x*10+ch-'0';
 27         ch=getchar();
 28     }
 29     return x*f;
 30 }
 31 //**************************************************************************************
 32 struct ss
 33 {
 34     int l,r,v;
 35     bool lazy;
 36 }tr[100000*5];
 37 int n,m;
 38 void build(int k,int s,int t)
 39 {
 40     tr[k].l=s;
 41     tr[k].r=t;
 42     if(s==t){
 43         return ;
 44     }
 45     int mid=(s+t)>>1;
 46     build(k<<1,s,mid);
 47     build(k<<1|1,mid+1,t);
 48 }
 49 void pushdown(int k)//设置好
 50 {
 51     if(!tr[k].lazy)return;
 52     tr[k<<1].lazy=!tr[k<<1].lazy;
 53     tr[k<<1|1].lazy=!tr[k<<1|1].lazy;
 54     tr[k<<1].v=tr[k<<1].r-tr[k<<1].l+1-tr[k<<1].v;
 55     tr[k<<1|1].v=tr[k<<1|1].r-tr[k<<1|1].l+1-tr[k<<1|1].v;
 56     tr[k].lazy=0;
 57 }
 58 void update(int k,int s,int t)
 59 {
 60     pushdown(k);
 61     if(tr[k].l==s&&tr[k].r==t)
 62     {
 63        tr[k].v=tr[k].r-tr[k].l+1-tr[k].v;
 64        if(tr[k].l!=tr[k].r) tr[k].lazy=1;//!!!!!!!
 65         return;
 66     }
 67     int mid=(tr[k].l+tr[k].r)>>1;
 68     if(t<=mid)update(k<<1,s,t);
 69     else if(s>mid)update(k<<1|1,s,t);
 70     else
 71     {
 72         update(k<<1,s,mid);
 73         update(k<<1|1,mid+1,t);
 74     }
 75     tr[k].v=tr[k<<1].v+tr[k<<1|1].v;
 76 }
 77 int ask(int k,int s,int t)
 78 {
 79     pushdown(k);
 80     if(s==tr[k].l&&tr[k].r==t)
 81     {
 82         return tr[k].v;
 83     }
 84     int mid=(tr[k].l+tr[k].r)>>1;
 85     if(t<=mid)  return ask(k<<1,s,t);
 86     else if(s>mid)return ask(k<<1|1,s,t);
 87     else{
 88         return ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t);
 89     }
 90 }
 91 int main()
 92 {
 93 
 94     scanf("%d%d",&n,&m);
 95     build(1,1,n);
 96     for(int i=1;i<=m;i++)
 97     {
 98         int t,x,y;
 99         scanf("%d%d%d",&t,&x,&y);
100         if(t==0)
101         {
102             update(1,x,y);
103         }
104         else printf("%d\n",ask(1,x,y));
105     }
106     return 0;
107 }

 

posted @ 2015-08-04 00:28  meekyan  阅读(289)  评论(0编辑  收藏  举报