FZU 1968 Twinkling lights III
Twinkling lights III
Time Limit: 8000ms
Memory Limit: 131072KB
This problem will be judged on FZU. Original ID: 196864-bit integer IO format: %I64d Java class name: Main
Twinkling lights一直以来都很好玩的游戏。或许你还记得FZU1069 Twinkling lights 和FZU1420 Twinkling lights II。现在,Bluewind改变了一下游戏规则,游戏将变得更好玩。
N盏灯排成一行,编号1..N,起初的时候,所有的灯是开着的。Bluewind将执行M个操作,操作分成五种:
C x y,把编号从x到y的灯都关掉,原来关着的灯保持不变。
S x y,把编号从x到y的灯都开起来,原来开着的灯依旧开着。
A x y,让编号从x到y的灯都改变状态,即把原来开的灯关了,原来关了的灯开起来。
Q x y,查询编号从x到y中开着的灯的个数。
L x y,查询编号从x到y中最长连续开着的灯的个数。
Input
第一行两个整数N,M(1<=N,M<=500,000)表示有N盏灯,M个操作。
接下来M行,每行按指定格式给出一个操作,其中(1<=x<=y<=N)。
Output
对于每条Q查询操作和L查询操作,输出相应的结果。
Sample Input
10 5 C 2 8 S 5 7 A 1 10 Q 1 10 L 1 10
Sample Output
4 3
Source
解题:线段树。。。那题HDU 3397 Sequence operation很像嘛
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int maxn = 500010; 5 struct node { 6 int lt,rt,cover; 7 } tree[maxn<<2]; 8 int ret; 9 void build(int L,int R,int v) { 10 tree[v].lt = L; 11 tree[v].rt = R; 12 tree[v].cover = 1; 13 if(L == R) return; 14 int mid = (L + R)>>1; 15 build(L,mid,v<<1); 16 build(mid+1,R,v<<1|1); 17 } 18 inline void pushup(int v) { 19 if(tree[v<<1].cover == tree[v<<1|1].cover) 20 tree[v].cover = tree[v<<1].cover; 21 else tree[v].cover = -1; 22 } 23 inline void pushdown(int v) { 24 if(tree[v].cover >= 0) { 25 tree[v<<1].cover = tree[v<<1|1].cover = tree[v].cover; 26 tree[v].cover = -1; 27 } 28 } 29 void update(int lt,int rt,int val,bool sel,int v) { 30 if(sel && tree[v].cover == val) return; 31 if(lt <= tree[v].lt && rt >= tree[v].rt && (sel || !sel && tree[v].cover >= 0)) { 32 if(sel) tree[v].cover = val; 33 else tree[v].cover ^= 1; 34 return; 35 } 36 pushdown(v); 37 if(lt <= tree[v<<1].rt) update(lt,rt,val,sel,v<<1); 38 if(rt >= tree[v<<1|1].lt) update(lt,rt,val,sel,v<<1|1); 39 pushup(v); 40 } 41 void query(int lt,int rt,int &ans,int &r,bool sel,int v) { 42 if(!tree[v].cover) return; 43 if(lt <= tree[v].lt && rt >= tree[v].rt && tree[v].cover > 0) { 44 if(sel) ans += tree[v].rt - tree[v].lt + 1; 45 else { 46 if(r + 1 == tree[v].lt) ans += tree[v].rt - tree[v].lt + 1; 47 else ans = tree[v].rt - tree[v].lt + 1; 48 } 49 r = tree[v].rt; 50 ret = max(ans,ret); 51 return; 52 } 53 pushdown(v); 54 if(lt <= tree[v<<1].rt) query(lt,rt,ans,r,sel,v<<1); 55 if(rt >= tree[v<<1|1].lt) query(lt,rt,ans,r,sel,v<<1|1); 56 pushup(v); 57 } 58 int main() { 59 int n,m,x,y,ans,r; 60 char op[3]; 61 while(~scanf("%d %d",&n,&m)) { 62 build(1,n,1); 63 while(m--) { 64 scanf("%s%d%d",op,&x,&y); 65 switch(op[0]) { 66 case 'C': 67 update(x,y,0,true,1); 68 break; 69 case 'S': 70 update(x,y,1,true,1); 71 break; 72 case 'A': 73 update(x,y,0,false,1); 74 break; 75 case 'Q': 76 ret = ans = r = 0; 77 query(x,y,ans,r,true,1); 78 printf("%d\n",ret); 79 break; 80 case 'L': 81 ret = ans = r = 0; 82 query(x,y,ans,r,false,1); 83 printf("%d\n",ret); 84 break; 85 } 86 } 87 } 88 return 0; 89 }
夜空中最亮的星,照亮我前行