InputT(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, ‘0‘ or ‘1‘ separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.OutputFor each output operation , output the result.Sample Input
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
Sample Output
5 2 6 5
感觉HOTEL一类的线段树题目已经练的差不多了,接下来开始练习扫描线。
1 #include <iostream> 2 //#include<bits/stdc++.h> 3 #include <stack> 4 #include <queue> 5 #include <map> 6 #include <set> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <math.h> 11 using namespace std; 12 int t,n,m; 13 const int MAX=1e5+5; 14 struct node 15 { 16 int left,mid,right; 17 int l,r; 18 int status; 19 int num; 20 int len() 21 { 22 return r-l+1; 23 } 24 void actl() 25 { 26 if(status!=-1) 27 num=left=mid=right=(status?len():0); 28 } 29 }st[10*MAX]; 30 void renew(int k) 31 { 32 st[k].num=st[2*k].num+st[2*k+1].num; 33 st[k].mid=max(st[2*k].mid,st[2*k+1].mid); 34 st[k].left=st[2*k].left; 35 st[k].right=st[2*k+1].right; 36 st[k].mid=max(st[k].mid,st[2*k].right+st[2*k+1].left); 37 if(st[2*k].left==st[2*k].len()) 38 st[k].left+=st[2*k+1].left; 39 if(st[2*k+1].right==st[2*k+1].len()) 40 st[k].right+=st[2*k].right; 41 } 42 void init(int l,int r,int k)//allright 43 { 44 st[k].l=l;st[k].r=r; 45 st[k].num=0; 46 st[k].status=-1; 47 if(l==r) 48 { 49 scanf("%d",&st[k].status); 50 st[k].actl(); 51 // st[k].num=1; 52 return; 53 } 54 init(l,(l+r)/2,2*k); 55 init((l+r)/2+1,r,2*k+1); 56 renew(k); 57 } 58 void pushdown(int k)//allright 59 { 60 if(st[k].status!=-1) 61 { 62 st[2*k].status=st[2*k+1].status=st[k].status; 63 st[2*k].actl(); 64 st[2*k+1].actl(); 65 st[k].status=-1; 66 } 67 } 68 int query(int ql,int qr,int k)//返回1的个数 69 { 70 if(st[k].l==ql&&st[k].r==qr) 71 return st[k].num; 72 int mid=(st[k].l+st[k].r)/2; 73 pushdown(k); 74 if(qr<=mid) 75 { 76 return query(ql,qr,2*k); 77 } 78 else if(ql>mid) 79 return query(ql,qr,2*k+1); 80 else 81 return query(ql,mid,2*k)+query(mid+1,qr,2*k+1); 82 } 83 int query_1(int ql,int qr,int k)//返回连续的1的个数 84 { 85 if(ql==st[k].l&&qr==st[k].r) 86 { 87 return st[k].mid; 88 } 89 int mid=(st[k].l+st[k].r)/2; 90 pushdown(k); 91 if(qr<=mid) 92 { 93 return query_1(ql,qr,2*k); 94 } 95 else if(ql>mid) 96 return query_1(ql,qr,2*k+1); 97 else 98 { 99 int an; 100 int zuo,you; 101 an=min(st[2*k].right,st[2*k].r-ql+1)+min(st[2*k+1].left,qr-st[2*k+1].l+1); 102 103 zuo=query_1(ql,mid,2*k);an=max(an,zuo); 104 you=query_1(mid+1,qr,2*k+1);an=max(an,you); 105 return an; 106 } 107 } 108 void update(int ul,int ur,int k,int val) 109 { 110 if(ul==st[k].l&&ur==st[k].r) 111 { 112 if(val<=1) 113 { 114 st[k].status=val; 115 st[k].actl(); 116 return; 117 } 118 else 119 { 120 if(st[k].status==0||st[k].status==1) 121 { 122 st[k].status=(st[k].status?0:1); 123 st[k].actl(); 124 return; 125 } 126 else 127 { 128 pushdown(k); 129 update(ul,(ul+ur)/2,2*k,val); 130 update((ul+ur)/2+1,ur,2*k+1,val); 131 renew(k); 132 return; 133 } 134 } 135 } 136 pushdown(k); 137 int mid=(st[k].l+st[k].r)/2; 138 if(ur<=mid) 139 update(ul,ur,2*k,val); 140 else if(ul>mid) 141 update(ul,ur,2*k+1,val); 142 else 143 { 144 update(ul,mid,2*k,val); 145 update(mid+1,ur,2*k+1,val); 146 } 147 renew(k); 148 } 149 int main() 150 { 151 scanf("%d",&t); 152 int x,y; 153 int opt; 154 while(t--) 155 { 156 scanf("%d %d",&n,&m); 157 init(0,n-1,1); 158 while(m--) 159 { 160 scanf("%d %d %d",&opt,&x,&y); 161 if(opt<3) 162 { 163 update(x,y,1,opt); 164 } 165 else if(opt==3) 166 printf("%d\n",query(x,y,1)); 167 else printf("%d\n",query_1(x,y,1)); 168 } 169 } 170 }
(线段树)hdoj 3397-Sequence operation
原文:http://www.cnblogs.com/quintessence/p/6485850.html