线段树专辑

这段时间研究研究线段树。

hh大牛的线段树专辑http://www.notonlysuccess.com/?p=59

1.HDOJ 1166 敌兵布阵 

代码
1
2
3 #include <iostream>
4 #include <cstdio>
5  #define LL(x) ((x)<<1)
6 #define RR(x) ((x)<<1|1)
7 using namespace std;
8
9 int n;
10 int num[50001];
11
12 struct segTree{
13 int l,r,v;
14 int callmid(){ return (l+r)/2; }
15 }st[150000];
16
17 int bd(int l,int r,int idx){
18 int mid;
19 st[idx].l=l;
20 st[idx].r=r;
21 if(l==r){
22 return st[idx].v=num[l];
23 }
24 mid=(l+r)/2;
25 return st[idx].v=bd(l,mid,LL(idx)) + bd(mid+1,r,RR(idx)) ;
26 }
27
28 void update(int a,int b,int idx){
29 int mid;
30 st[idx].v+=b;
31 if(st[idx].r==st[idx].l){
32 return ;
33 }
34 mid=st[idx].callmid();
35 if(a<=mid){
36 update(a,b,LL(idx));
37 }
38 else{
39 update(a,b,RR(idx));
40 }
41 }
42
43 int query(int a,int b,int idx){
44 int mid;
45 if(a==st[idx].l && b==st[idx].r)
46 return st[idx].v;
47 mid=st[idx].callmid();
48 if(b<=mid){
49 return query(a,b,LL(idx));
50 }
51 else if(mid<a){
52 return query(a,b,RR(idx));
53 }
54 else{
55 return query(a,mid,LL(idx)) + query(mid+1,b,RR(idx));
56 }
57 }
58
59 int main(){
60 // freopen("c:/aaa.txt","r",stdin);
61 int T,i,j;
62 char str[10];
63 scanf("%d",&T);
64
65 for(i=1;i<=T;++i){
66 printf("Case %d:\n",i);
67 scanf("%d",&n);
68 for(j=1;j<=n;++j){
69 scanf("%d",&num[j]);
70 }
71 bd(1,n,1);
72
73 while(scanf("%s",str)){
74 int a,b;
75 if(strcmp(str,"End")==0) break;
76 scanf("%d%d",&a,&b);
77 switch(str[0]){
78 case 'A':
79 update(a,b,1);
80 break;
81 case 'Q':
82 printf("%d\n",query(a,b,1));
83 break;
84 case 'S':
85 update(a,-b,1);
86 break;
87 }
88 }
89 }
90 return 0;
91 }
92

2.HDOJ 1754 I Hate It

3.hdoj 1698 Just a Hook

代码
1 写了个线段树,一交,tle,囧
2 //TLE
3 #include <iostream>
4 #define LL(x) ((x)<<1)
5 #define RR(x) ((x)<<1|1)
6 using namespace std;
7 int n;
8 struct segTree{
9 int r,l,v;
10 int callmid(){ return (r+l)/2; }
11 }st[300000];
12 int bd(int l,int r,int kind,int idx){
13 int mid;
14 st[idx].l=l;
15 st[idx].r=r;
16 if(l==r){
17 return st[idx].v=kind;
18 }
19 mid=st[idx].callmid();
20 return st[idx].v=bd(l,mid,kind,LL(idx))+bd(mid+1,r,kind,RR(idx));
21 }
22
23 int query(int l,int r,int idx){
24 int mid;
25 if(r<l) return 0;
26 if(l==st[idx].l && r==st[idx].r){
27 return st[idx].v;
28 }
29 mid=st[idx].callmid();
30 if(r<=mid){
31 return query(l,r,LL(idx));
32 }
33 else if(l>mid){
34 return query(l,r,RR(idx));
35 }
36 else{
37 return query(l,mid,LL(idx))+query(mid+1,r,RR(idx));
38 }
39 }
40
41 int update(int l,int r,int kind,int idx){
42 int mid;
43 if(l==st[idx].l && r==st[idx].r){
44 return bd(l,r,kind,idx);
45 }
46 mid=st[idx].callmid();
47 if(r<=mid){
48 return st[idx].v=st[RR(idx)].v+update(l,r,kind,LL(idx));
49 }else if(l>mid){
50 return st[idx].v=st[LL(idx)].v+update(l,r,kind,RR(idx));
51 }else{
52 return st[idx].v=update(l,mid,kind,LL(idx))+update(mid+1,r,kind,RR(idx));
53 }
54 }
55
56 void crazyac(){
57 int m,a,b,kind;
58 scanf("%d%d",&n,&m);
59 bd(1,n,1,1);
60 while(m--){
61 scanf("%d%d%d",&a,&b,&kind);
62 update(a,b,kind,1);
63 }
64 printf("The total value of the hook is %d.\n",st[1].v);
65 }
66 int main(){
67 // freopen("c:/aaa.txt","r",stdin);
68 int T,i;
69 scanf("%d",&T);
70 for(i=1;i<=T;++i){
71 printf("Case %d: ",i);
72 crazyac();
73 }
74 return 0;
75 }
76 想了下,超时的原因是每次更新,我都跟新到了点,其实更新到线段就行了,设置一个属性值,改了下,781MS
77 #include <iostream>
78 #define LL(x) ((x)<<1)
79 #define RR(x) ((x)<<1|1)
80 using namespace std;
81
82 int n;
83 struct segTree{
84 int r,l,v;
85 }st[300000];
86
87 void bd(int l,int r,int idx){
88 int mid;
89 st[idx].l=l;
90 st[idx].r=r;
91 st[idx].v=1;
92 if(l==r) return ;
93 mid=(l+r)/2;
94 bd(l,mid,LL(idx));
95 bd(mid+1,r,RR(idx));
96 }
97
98 void update(int l,int r,int kind,int idx){
99 int mid;
100 if(st[idx].l>=l && st[idx].r<=r){
101 st[idx].v=kind;
102 return;
103 }
104 if(st[idx].v!=-1){
105 st[LL(idx)].v=st[RR(idx)].v=st[idx].v;
106 st[idx].v=-1;
107 }
108 mid=(st[idx].l+st[idx].r)/2;
109 if(l<=mid) update(l,r,kind,LL(idx));
110 if(r>mid) update(l,r,kind,RR(idx));
111 }
112
113 int query(int l,int r,int idx){
114 int mid;
115 mid=(st[idx].l+st[idx].r)/2;
116 if(st[idx].l==l && st[idx].r==r){
117 if(st[idx].v!=-1){
118 return (st[idx].r-st[idx].l+1)*st[idx].v;
119 }else{
120 return query(l,mid,LL(idx))+query(mid+1,r,RR(idx));
121 }
122 }
123 if(r<=mid){
124 return query(l,r,LL(idx));
125 }else if(l>mid){
126 return query(l,r,RR(idx));
127 }
128 else {
129 return query(l,mid,LL(idx))+query(mid+1,r,RR(idx));
130 }
131 }
132
133 void crazyac(){
134 int m,a,b,kind;
135 scanf("%d%d",&n,&m);
136 bd(1,n,1);
137 while(m--){
138 scanf("%d%d%d",&a,&b,&kind);
139 update(a,b,kind,1);
140 }
141 printf("The total value of the hook is %d.\n",query(1,n,1));
142 }
143
144 int main(){
145 // freopen("c:/aaa.txt","r",stdin);
146 int T,i;
147 scanf("%d",&T);
148 for(i=1;i<=T;++i){
149 printf("Case %d: ",i);
150 crazyac();
151 }
152 return 0;
153 }
154 我擦,这题还可以是暴利,而且时间更少421MS,代码量也区区500+ B#include <iostream>
155 using namespace std;
156
157 int num[100005][3];
158
159 int main(){
160 // freopen("c:/aaa.txt","r",stdin);
161 int T,n,m,a,b,c,v,sum,i,j;
162 scanf("%d",&T);
163 for(i=1;i<=T;++i){
164 printf("Case %d: The total value of the hook is ",i);
165 scanf("%d%d",&n,&m);
166 for(j=1;j<=m;++j){
167 scanf("%d%d%d",&num[j][0],&num[j][1],&num[j][2]);
168 }
169 sum=0;
170 for(j=1;j<=n;++j){
171 v=1;
172 for(int k=m;k>=1;--k){
173 if(j>=num[k][0] && j<=num[k][1]){
174 v=num[k][2];
175 break;
176 }
177 }
178 sum+=v;
179 }
180 printf("%d.\n",sum);
181 }
182 return 0;
183 }
184

4.Pku 2777 Count Color

代码
1
2
3 #include <iostream>
4 #include <cstdio>
5 #include <cstring>
6 #define LL(x) ((x)<<1)
7 #define RR(x) ((x)<<1|1)
8 using namespace std;
9
10 int n,m;
11 bool mark[35];
12
13 struct segTree{
14 int l,r,v;
15 }st[300000];
16 void bd(int l,int r,int idx){
17 int mid;
18 st[idx].l=l;
19 st[idx].r=r;
20 st[idx].v=1;
21 if(l==r) return ;
22 mid=(l+r)/2;
23 bd(l,mid,LL(idx));
24 bd(mid+1,r,RR(idx));
25 }
26
27 void update(int l,int r,int c,int idx){
28 int mid;
29 if(st[idx].l>=l && st[idx].r<=r){
30 st[idx].v=c;
31 return;
32 }
33 mid=(st[idx].r+st[idx].l)/2;
34 if(st[idx].v!=-1){
35 st[LL(idx)].v=st[RR(idx)].v=st[idx].v;
36 st[idx].v=-1;
37 }
38 if(l<=mid) update(l,r,c,LL(idx));
39 if(r>mid) update(l,r,c,RR(idx));
40 }
41
42 void query(int l,int r,int idx){
43 int mid;
44 if(st[idx].v!=-1){
45 mark[st[idx].v]=1;
46 }
47 else{
48 mid=(st[idx].r+st[idx].l)/2;
49 if(r<=mid){
50 query(l,r,LL(idx));
51 }
52 else if(l>mid){
53 query(l,r,RR(idx));
54 }
55 else {
56 query(l,mid,LL(idx));
57 query(mid+1,r,RR(idx));
58 }
59 }
60 }
61
62 int main(){
63 // freopen("c:/aaa.txt","r",stdin);
64 int o,l,r,c,i,temp;
65 char ch[5];
66 while(scanf("%d%d%d",&n,&m,&o)!=EOF){
67 bd(1,n,1);
68 while(o--){
69 scanf("%s",ch);
70 if(ch[0]=='C'){
71 scanf("%d%d%d",&l,&r,&c);
72 if(l>r){
73 temp=l;
74 l=r;
75 r=temp;
76 }
77 update(l,r,c,1);
78 }
79 else{
80 scanf("%d%d",&l,&r);
81 if(l>r){
82 temp=l;
83 l=r;
84 r=temp;
85 }
86 memset(mark,0,sizeof(mark));
87 query(l,r,1);
88 int cnt=0;
89 for(i=1;i<=m;++i){
90 if(mark[i])++cnt;
91 }
92 printf("%d\n",cnt);
93 }
94 }
95 }
96 return 0;
97 }
98

5.pku 3468 A Simple Problem With Integers  

代码
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #define LL(x) ((x)<<1)
5 #define RR(x) ((x)<<1|1)
6 using namespace std;
7 typedef __int64 lld;
8
9 int n;
10 int num[100010];
11
12 struct segTree{
13 int l,r,add;
14 lld v;
15 }st[300000];
16
17 lld bd(int l,int r,int idx){
18 int mid;
19 st[idx].l=l;
20 st[idx].r=r;
21 st[idx].add=0;
22 if(l==r){
23 return st[idx].v=num[l];
24 }
25 mid=(l+r)/2;
26 return st[idx].v=bd(l,mid,LL(idx))+bd(mid+1,r,RR(idx));
27 }
28
29 void update(int l,int r,int a,int idx){
30 int mid;
31 if(st[idx].l>=l && st[idx].r<=r){
32 st[idx].v+=(__int64)(st[idx].r-st[idx].l+1)*a;
33 st[idx].add+=a;
34 return;
35 }
36
37 if(st[idx].add){
38 st[LL(idx)].v+=(__int64)(st[LL(idx)].r-st[LL(idx)].l+1)*st[idx].add;
39 st[RR(idx)].v+=(__int64)(st[RR(idx)].r-st[RR(idx)].l+1)*st[idx].add;
40 st[LL(idx)].add+=st[idx].add;
41 st[RR(idx)].add+=st[idx].add;
42 st[idx].add=0;
43 }
44
45 mid=(st[idx].l+st[idx].r)/2;
46 if(l<=mid) update(l,r,a,LL(idx));
47 if(r>mid) update(l,r,a,RR(idx));
48 st[idx].v=st[LL(idx)].v+st[RR(idx)].v;
49 }
50
51 lld query(int l,int r,int idx){
52 int mid;
53 mid=(st[idx].l+st[idx].r)/2;
54 if(l==st[idx].l && r==st[idx].r){
55 return st[idx].v;
56 }
57
58 if(st[idx].add){
59 st[LL(idx)].v+=(__int64)(st[LL(idx)].r-st[LL(idx)].l+1)*st[idx].add;
60 st[RR(idx)].v+=(__int64)(st[RR(idx)].r-st[RR(idx)].l+1)*st[idx].add;
61 st[LL(idx)].add+=st[idx].add;
62 st[RR(idx)].add+=st[idx].add;
63 st[idx].add=0;
64 }
65
66 if(r<=mid){
67 return query(l,r,LL(idx));
68 }else if(l>mid){
69 return query(l,r,RR(idx));
70 }else {
71 return query(l,mid,LL(idx))+query(mid+1,r,RR(idx));
72 }
73 }
74
75 int main(){
76 // freopen("c:/aaa.txt","r",stdin);
77 int m,i,l,r,a;
78 char ch[10];
79 while(scanf("%d%d",&n,&m)!=EOF){
80 for(i=1;i<=n;++i){
81 scanf("%d",&num[i]);
82 }
83 bd(1,n,1);
84 while(m--){
85 scanf("%s",ch);
86 if(ch[0]=='Q'){
87 scanf("%d%d",&l,&r);
88 printf("%I64d\n",query(l,r,1));
89 }
90 else{
91 scanf("%d%d%d",&l,&r,&a);
92 update(l,r,a,1);
93 }
94 }
95 }
96 return 0;
97 }
98

6.pku 2528 Mayor’s posters

代码
1 #include <iostream>
2 #include <algorithm>
3 #include <cstdio>
4 #include <cstring>
5 #define LL(x) ((x)<<1)
6 #define RR(x) ((x)<<1|1)
7 using namespace std;
8
9 struct point{
10 int x,y;
11 }p[10001];
12
13 struct segTree{
14 int l,r,col;
15 int callmid(){ return (l+r)/2;}
16 }st[70000];
17
18 int pos[20002];
19 int n,m,ans;
20 bool mark[10001];
21
22 void bd(int l,int r,int idx){
23 int mid;
24 st[idx].l=l;
25 st[idx].r=r;
26 st[idx].col=-1;
27 if(l==r) return ;
28 mid=st[idx].callmid();
29 bd(l,mid,LL(idx));
30 bd(mid+1,r,RR(idx));
31 }
32
33 void update(int l,int r,int col,int idx){
34 int mid;
35 if(st[idx].l>=l && st[idx].r<=r){
36 st[idx].col=col;
37 return ;
38 }
39 if(st[idx].col!=-1){
40 st[LL(idx)].col=st[RR(idx)].col=st[idx].col;
41 st[idx].col=-1;
42 }
43 mid=st[idx].callmid();
44 if(l<=mid) update(l,r,col,LL(idx));
45 if(r>mid) update(l,r,col,RR(idx));
46 }
47
48 void query(int l,int r,int idx){
49 int mid;
50 if(st[idx].col!=-1){
51 if(!mark[st[idx].col]){
52 ++ans;
53 mark[st[idx].col]=1;
54 }
55 }
56 else{
57 mid=st[idx].callmid();
58 if(r<=mid){
59 query(l,r,LL(idx));
60 }
61 else if(l>mid){
62 query(l,r,RR(idx));
63 }
64 else{
65 query(l,mid,LL(idx));
66 query(mid+1,r,RR(idx));
67 }
68 }
69 }
70
71 int get(int x){
72 int l,r,mid;
73 l=0;
74 r=m-1;
75 while(l<=r){
76 mid=(l+r)>>1;
77 if(pos[mid]==x){
78 return mid;
79 }
80 else if(pos[mid]<x){
81 l=mid+1;
82 }
83 else{
84 r=mid-1;
85 }
86 }
87 return -1;
88 }
89
90 int main(){
91 // freopen("c:/aaa.txt","r",stdin);
92 int T,i;
93 scanf("%d",&T);
94 while(T--){
95 scanf("%d",&n);
96 for(i=0;i<n;++i){
97 scanf("%d%d",&p[i].x,&p[i].y);
98 pos[LL(i)]=p[i].x;
99 pos[RR(i)]=p[i].y;
100 }
101 sort(pos,pos+2*n);
102 m=0;
103 for(i=0;i<2*n;++i){
104 if(i==0 || pos[i-1]!=pos[i]){
105 pos[m++]=pos[i];
106 }
107 }
108
109 bd(0,m-1,1);
110 for(i=0;i<n;++i){
111 int a=get(p[i].x);
112 int b=get(p[i].y);
113 update(a,b,i,1);
114 }
115 memset(mark,0,sizeof(mark));
116 ans=0;
117 query(0,m-1,1);
118 printf("%d\n",ans);
119 }
120 return 0;
121 }
122

7.pku 3667 Hotel

代码
1
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #define LL(x) ((x)<<1)
6 #define RR(x) ((x)<<1|1)
7 using namespace std;
8
9 int n;
10
11 struct segTree{
12 int l,r,v;
13 int lv,rv,all;
14 int callmid(){ return (l+r)>>1; }
15 int dis(){ return (r-l+1); }
16 void doit(){ lv=rv=all=(v) ? 0 : dis(); }
17 }st[250000];
18 int max(int a,int b){
19 if(a>b) return a;
20 else return b;
21 }
22 void bd(int l,int r,int idx){
23 int mid;
24 st[idx].l=l;
25 st[idx].r=r;
26 st[idx].v=-1;
27 st[idx].lv=st[idx].rv=st[idx].all=st[idx].dis();
28 if(l==r) return ;
29 mid=st[idx].callmid();
30 bd(l,mid,LL(idx));
31 bd(mid+1,r,RR(idx));
32 }
33 void update(int l,int r,int a,int idx){
34 int mid;
35 if(st[idx].l>=l && st[idx].r<=r){
36 st[idx].v=a;
37 st[idx].doit();
38 return;
39 }
40
41 if(st[idx].v!=-1){
42 st[LL(idx)].v=st[RR(idx)].v=st[idx].v;
43 st[LL(idx)].doit();
44 st[RR(idx)].doit();
45 st[idx].v=-1;
46 }
47
48 mid=st[idx].callmid();
49 if(l<=mid){ update(l,r,a,LL(idx)); }
50 if(r>mid){ update(l,r,a,RR(idx)); }
51
52 st[idx].all=max( st[LL(idx)].rv+st[RR(idx)].lv , max(st[LL(idx)].all,st[RR(idx)].all) );
53 st[idx].lv=st[LL(idx)].lv;
54 st[idx].rv=st[RR(idx)].rv;
55 if(st[LL(idx)].lv==st[LL(idx)].dis()){
56 st[idx].lv+=st[RR(idx)].lv;
57 }
58 if(st[RR(idx)].rv==st[RR(idx)].dis()){
59 st[idx].rv+=st[LL(idx)].rv;
60 }
61 }
62
63 int query(int a,int idx){
64 if(st[idx].l==st[idx].r && a==1)
65 return st[idx].l;
66
67 if(st[idx].v!=-1){
68 st[LL(idx)].v=st[RR(idx)].v=st[idx].v;
69 st[LL(idx)].doit();
70 st[RR(idx)].doit();
71 st[idx].v=-1;
72 }
73
74 if(st[LL(idx)].all>=a){
75 return query(a,LL(idx));
76 }
77 else if(st[LL(idx)].rv+st[RR(idx)].lv>=a){
78 return st[LL(idx)].r-st[LL(idx)].rv+1;
79 }
80 else if(st[RR(idx)].all>=a){
81 return query(a,RR(idx));
82 }
83 else return 0;
84 }
85
86 int main(){
87 // freopen("c:/aaa.txt","r",stdin);
88 int m;
89 while(scanf("%d%d",&n,&m)!=EOF){
90 bd(1,n,1);
91 while(m--){
92 int a,b,c,d;
93 scanf("%d",&a);
94 if(a==1){
95 scanf("%d",&b);
96 d=query(b,1);
97 printf("%d\n",d);
98 if(d){
99 update(d,d+b-1,1,1);
100 }
101 }
102 else{
103 scanf("%d%d",&b,&c);
104 update(b,b+c-1,0,1);
105 }
106 }
107 }
108 return 0;
109 }
110

8.hdoj 2795 Billboard

代码
1
2
3 表示做了这么多线段树,第一次一次AC。
4
5 而且耗时4015MS,悲剧地排在倒数第四,囧。。。。
6
7 #include <iostream>
8 #include <cstdio>
9 #include <cstring>
10 #define LL(x) ((x)<<1)
11 #define RR(x) ((x)<<1|1)
12 using namespace std;
13
14 int n,w,h;
15
16 struct segTree{
17 int l,r,v;
18 int callmid(){ return (l+r)>>1; }
19 }st[800000];
20
21 int max(int a,int b){
22 if(a<b) return b;
23 else return a;
24 }
25
26 void bd(int l,int r,int idx){
27 int mid;
28 st[idx].l=l;
29 st[idx].r=r;
30 st[idx].v=w;
31 if(l==r) return ;
32 mid=st[idx].callmid();
33 bd(l,mid,LL(idx));
34 bd(mid+1,r,RR(idx));
35 }
36
37
38 int query(int a,int idx){
39 if(st[idx].v<a){
40 return -1;
41 }
42 else if(st[idx].l==st[idx].r){
43 return st[idx].l;
44 }
45 else if(st[LL(idx)].v>=a){
46 return query(a,LL(idx));
47 }
48 else{
49 return query(a,RR(idx));
50 }
51 }
52
53 void update(int l,int r,int a,int idx){
54 int mid;
55 if(st[idx].l>=l && st[idx].r<=r){
56 st[idx].v+=a;
57 return ;
58 }
59 mid=st[idx].callmid();
60 if(l<=mid) update(l,r,a,LL(idx));
61 if(r>mid) update(l,r,a,RR(idx));
62 st[idx].v=max(st[LL(idx)].v,st[RR(idx)].v);
63 }
64
65
66 int main(){
67 int a,b,o;
68 while(scanf("%d%d%d",&h,&w,&o)==3){
69 h<o ? n=h : n=o;
70 bd(1,n,1);
71 while(o--){
72 scanf("%d",&a);
73 b=query(a,1);
74 printf("%d\n",b);
75 if(b!=-1) update(b,b,-a,1);
76 }
77 }
78 return 0;
79 }
80
81

9.HDOJ 1540 Tunnel Warfare

代码
1 想用一个vec和一个数组来维护,无奈越界了一个上午。只好按照hh博客的代码改,把数组去掉
2 //越界的代码
3
4 #include <iostream>
5 #include <cstdio>
6 #include <cstring>
7 #include <vector>
8 #include <algorithm>
9 #define LL(x) ((x)<<1)
10 #define RR(x) ((x)<<1|1)
11 using namespace std;
12
13
14 struct Node{
15 int s,e;
16 };
17 vector<Node> vec;
18
19 struct segTree{
20 int l,r,col;
21 int lv,rv,v;
22 int callmid(){ return (l+r)>>1; }
23 int dis(){ return (r-l+1); }
24 void doit(){ lv=rv=v=(col)? 0 : dis(); }
25 }st[250000];
26
27 int num[50005];
28 int n;
29
30 int max(int a,int b){
31 if(a<b) return b;
32 else return a;
33 }
34
35 void bd(int l,int r,int idx){
36 int mid;
37 st[idx].l=l;
38 st[idx].r=r;
39 st[idx].col=0;
40 st[idx].doit();
41 if(l==r) return;
42 mid=st[idx].callmid();
43 bd(l,mid,LL(idx));
44 bd(mid+1,r,RR(idx));
45 }
46 void update(int l,int r,int col,int idx){
47 int mid;
48 if(st[idx].l>=l && st[idx].r<=r){
49 st[idx].col=col;
50 st[idx].doit();
51 return;
52 }
53
54 if(st[idx].col!=-1){
55 st[LL(idx)].col=st[RR(idx)].col=st[idx].col;
56 st[LL(idx)].doit();
57 st[RR(idx)].doit();
58 st[idx].col=-1;
59 }
60
61 mid=st[idx].callmid();
62 if(l<=mid) update(l,r,col,LL(idx));
63 if(r>mid) update(l,r,col,RR(idx));
64 st[idx].v=max(st[LL(idx)].rv+st[RR(idx)].lv,max(st[LL(idx)].v,st[RR(idx)].v));
65 st[idx].lv=st[LL(idx)].lv;
66 st[idx].rv=st[RR(idx)].rv;
67 if(st[LL(idx)].lv==st[LL(idx)].dis()){
68 st[idx].lv+=st[RR(idx)].lv;
69 }
70 if(st[RR(idx)].rv==st[RR(idx)].dis()){
71 st[idx].rv+=st[LL(idx)].rv;
72 }
73 }
74 int query(int a,int idx){
75 if(st[idx].l==st[idx].r && a==1){
76 return st[idx].l;
77 }
78
79 if(st[idx].col!=-1){
80 st[LL(idx)].col=st[RR(idx)].col=st[idx].col;
81 st[LL(idx)].doit();
82 st[RR(idx)].doit();
83 st[idx].col=-1;
84 }
85
86 if(st[LL(idx)].v>=a){
87 return query(a,LL(idx));
88 }
89 else if(st[LL(idx)].rv+st[RR(idx)].lv>=a){
90 return st[LL(idx)].r-st[LL(idx)].rv+1;
91 }
92 else if(st[RR(idx)].v>=a){
93 return query(a,RR(idx));
94 }
95 else return 0;
96 }
97 int Bin(int x){
98 int l,r,mid;
99 l=0;
100 r=vec.size()-1;
101 while(l<=r){
102 mid=(l+r)>>1;
103 if(vec[mid].s<x){
104 l=mid+1;
105 }
106 else r=mid-1;
107 }
108 return l;
109 }
110 Node myfree(int x){
111 Node nd;
112 int a,b,i,v;
113 if(num[x]==0){
114 nd.s=nd.e=0;
115 return nd;
116 }
117 v=num[x];
118 for(i=x;i>=1;--i){
119 if(num[i]!=v) break;
120 }
121 a=++i;
122
123 for(i=x;i<=n;++i){
124 if(num[i]!=v) break;
125 }
126 b=--i;
127
128 nd.s=a;
129 nd.e=b;
130 return nd;
131 }
132
133 int main(){
134 // freopen("c:/aaa.txt","r",stdin);
135 int o,i;
136 char str[10];
137 while(scanf("%d%d",&n,&o)==2){
138 bd(1,n,1);
139 vec.clear();
140 memset(num,0,sizeof(0));
141 while(o--){
142 scanf("%s",str);
143 if(str[0]=='R'){
144 update(1,n,0,1);
145 memset(num,0,sizeof(0));
146 vec.clear();
147 puts("Reset Now");
148 }
149 else if(str[0]=='N'){
150 int a,b,c;
151 scanf("%d",&a);
152 b=query(a,1);
153 if(b){
154 printf("New at %d\n",b);
155 update(b,b+a-1,1,1);
156 for(i=b;i<=b+a-1;++i){ num[i]=o; }
157 Node nd;
158 nd.s=b;
159 nd.e=b+a-1;
160 c=Bin(b);
161 vec.insert(vec.begin()+c,nd);
162 }
163 else puts("Reject New");
164 }
165 else if(str[0]=='F'){
166 Node nd;
167 int a;
168 scanf("%d",&a);
169 nd=myfree(a);
170 if(nd.s){
171 printf("Free from %d to %d\n",nd.s,nd.e);
172 update(nd.s,nd.e,0,1);
173 for(i=0;i<vec.size();++i){
174 if(vec[i].s==nd.s) break;
175 }
176 vec.erase(vec.begin()+i);
177 for(i=nd.s;i<=nd.e;++i){
178 num[i]=0;
179 }
180 }
181 else puts("Reject Free");
182 }
183 else if(str[0]=='G'){
184 int a;
185 scanf("%d",&a);
186 if(a<=vec.size())
187 printf("Get at %d\n",vec[a-1].s);
188 else puts("Reject Get");
189 }
190 }
191 }
192 return 0;
193 }
194 //AC后的代码
195
196 #include <iostream>
197 #include <cstdio>
198 #include <cstring>
199 #include <vector>
200 #include <algorithm>
201 #define LL(x) ((x)<<1)
202 #define RR(x) ((x)<<1|1)
203 using namespace std;
204
205
206 struct Node{
207 int s,e;
208 };
209 vector<Node> vec;
210
211 struct segTree{
212 int l,r,col;
213 int lv,rv,v;
214 int callmid(){ return (l+r)>>1; }
215 int dis(){ return (r-l+1); }
216 void doit(){ lv=rv=v=(col)? 0 : dis(); }
217 }st[250000];
218
219 int n;
220
221
222
223 int max(int a,int b){
224 if(a<b) return b;
225 else return a;
226 }
227
228
229
230 void bd(int l,int r,int idx){
231 int mid;
232 st[idx].l=l;
233 st[idx].r=r;
234 st[idx].col=0;
235 st[idx].doit();
236 if(l==r) return;
237 mid=st[idx].callmid();
238 bd(l,mid,LL(idx));
239 bd(mid+1,r,RR(idx));
240 }
241
242 void update(int l,int r,int col,int idx){
243 int mid;
244 if(st[idx].l>=l && st[idx].r<=r){
245 st[idx].col=col;
246 st[idx].doit();
247 return;
248 }
249
250 if(st[idx].col!=-1){
251 st[LL(idx)].col=st[RR(idx)].col=st[idx].col;
252 st[LL(idx)].doit();
253 st[RR(idx)].doit();
254 st[idx].col=-1;
255 }
256
257 mid=st[idx].callmid();
258 if(l<=mid) update(l,r,col,LL(idx));
259 if(r>mid) update(l,r,col,RR(idx));
260
261 st[idx].v=max(st[LL(idx)].rv+st[RR(idx)].lv,max(st[LL(idx)].v,st[RR(idx)].v));
262 st[idx].lv=st[LL(idx)].lv;
263 st[idx].rv=st[RR(idx)].rv;
264 if(st[LL(idx)].lv==st[LL(idx)].dis()){
265 st[idx].lv+=st[RR(idx)].lv;
266 }
267 if(st[RR(idx)].rv==st[RR(idx)].dis()){
268 st[idx].rv+=st[LL(idx)].rv;
269 }
270 }
271
272 int query(int a,int idx){
273 if(st[idx].l==st[idx].r && a==1){
274 return st[idx].l;
275 }
276
277 if(st[idx].col!=-1){
278 st[LL(idx)].col=st[RR(idx)].col=st[idx].col;
279 st[LL(idx)].doit();
280 st[RR(idx)].doit();
281 st[idx].col=-1;
282 }
283
284 if(st[LL(idx)].v>=a){
285 return query(a,LL(idx));
286 }
287 else if(st[LL(idx)].rv+st[RR(idx)].lv>=a){
288 return st[LL(idx)].r-st[LL(idx)].rv+1;
289 }
290 else if(st[RR(idx)].v>=a){
291 return query(a,RR(idx));
292 }
293 else return 0;
294 }
295
296 int Bin(int x){
297 int l,r,mid;
298 l=0;
299 r=vec.size()-1;
300 while(l<=r){
301 mid=(l+r)>>1;
302 if(vec[mid].s<=x){
303 l=mid+1;
304 }
305 else r=mid-1;
306 }
307 return l;
308 }
309
310
311 int main(){
312 // freopen("c:/aaa.txt","r",stdin);
313 int o,i;
314 char str[10];
315 while(scanf("%d%d",&n,&o)==2){
316 bd(1,n,1);
317 vec.clear();
318 while(o--){
319 scanf("%s",str);
320 if(str[0]=='R'){
321 update(1,n,0,1);
322 vec.clear();
323 puts("Reset Now");
324 }
325 else if(str[0]=='N'){
326 int a,b,c;
327 scanf("%d",&a);
328 b=query(a,1);
329 if(b){
330 printf("New at %d\n",b);
331 update(b,b+a-1,1,1);
332 Node nd;
333 nd.s=b;
334 nd.e=b+a-1;
335 c=Bin(b);
336 vec.insert(vec.begin()+c,nd);
337 }
338 else puts("Reject New");
339 }
340 else if(str[0]=='F'){
341 Node nd;
342 int a,b;
343 scanf("%d",&a);
344 b=Bin(a)-1;
345 if(b==-1 || vec[b].e<a){
346 puts("Reject Free");
347 }
348 else {
349 printf("Free from %d to %d\n",vec[b].s,vec[b].e);
350 update(vec[b].s,vec[b].e,0,1);
351 vec.erase(vec.begin()+b);
352 }
353 }
354 else if(str[0]=='G'){
355 int a;
356 scanf("%d",&a);
357 if(a<=vec.size())
358 printf("Get at %d\n",vec[a-1].s);
359 else puts("Reject Get");
360 }
361 }
362 printf("\n");
363 }
364 return 0;
365 }
366

10.Hdoj 1542 Atlantis

代码
1
2
3 //搞了N久才搞出来,悲剧。一交0MS,欣喜若狂,打开statistic一看,傻了。。。
4 按各个矩形的横边从低往高,不断更新线段树
5
6 #include <cstdio>
7 #include <cstring>
8 #include <algorithm>
9 #define LL(x) ((x)<<1)
10 #define RR(x) ((x)<<1|1)
11 using namespace std;
12
13 struct segment{
14 double l,r,h;
15 int cnt;
16 }ss[205];
17
18 double pos[205];
19 struct segTree{
20 int l,r,col;
21 double v;
22 int callmid(){ return (l + r) >> 1; }
23 }st[1000];
24
25 bool cmp(segment a, segment b){
26 return a.h < b.h;
27 }
28
29 int n,k;
30 void bd(int l,int r,int idx){
31 int mid;
32 st[idx].l = l;
33 st[idx].r = r;
34 st[idx].v = 0;
35 st[idx].col = 0;
36 if(l == r) return ;
37 mid = st[idx].callmid();
38 bd(l,mid,LL(idx));
39 bd(mid+1,r,RR(idx));
40 }
41 void fix(int idx){
42 if(st[idx].col){
43 st[idx].v = pos[st[idx].r+1] - pos[st[idx].l];
44 }
45 else if(st[idx].l == st[idx].r) {
46 st[idx].v = 0;
47 }
48 else {
49 st[idx].v = st[LL(idx)].v + st[RR(idx)].v;
50 }
51 }
52 void update(int l,int r,int c,int idx){
53 int mid;
54 if(st[idx].l >= l && st[idx].r <= r){
55 st[idx].col += c;
56 fix(idx);
57 return;
58 }
59
60 mid = st[idx].callmid();
61 if(l <= mid) update(l,r,c,LL(idx));
62 if(r > mid) update(l,r,c,RR(idx));
63
64 fix(idx);
65 }
66 int Bin(double x,int r){
67 int l,mid;
68 l = 0;
69 while(l <= r){
70 mid = (l + r) >> 1;
71 if(pos[mid] == x) return mid;
72 if(pos[mid] < x){
73 l = mid + 1;
74 }
75 else {
76 r = mid - 1;
77 }
78 }
79 return -1;
80 }
81 int main(){
82 // freopen("c:/aaa.txt","r",stdin);
83
84 int i,ca=0;
85 double a,b,c,d,l,r,ans;
86 while(scanf("%d",&n),n){
87 printf("Test case #%d\n",++ca);
88 for(i=0;i<n;++i){
89 scanf("%lf %lf %lf %lf",&a, &b, &c, &d);
90 pos[2*i] = a;
91 pos[2*i+1] = c;
92 ss[2*i].l = ss[2*i+1].l = a;
93 ss[2*i].r = ss[2*i+1].r = c;
94 ss[2*i].h = b;
95 ss[2*i].cnt = 1;
96 ss[2*i+1].h = d;
97 ss[2*i+1].cnt = -1;
98 }
99
100 sort(ss,ss + 2*n,cmp);
101 sort(pos,pos + 2*n);
102
103
104 k = 0;
105 for(i=0;i<2*n;++i){
106 if(i==0 || pos[i]!=pos[i-1])
107 pos[k++]=pos[i];
108 }
109
110 bd(0,k-1,1);
111 ans=0;
112 for(i=0;i<2*n;++i){
113 l = Bin(ss[i].l,k-1);
114 r = Bin(ss[i].r,k-1) - 1;
115 update(l,r,ss[i].cnt,1);
116 ans += st[1].v * (ss[i+1].h - ss[i].h);
117 }
118
119 printf("Total explored area: %.2lf\n\n",ans);
120 }
121 return 0;
122 }
123

11.Hdoj 1255 覆盖的面积

代码
1 //1515ms - -!
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #define LL(x) ((x)<<1)
6 #define RR(x) ((x)<<1|1)
7 using namespace std;
8
9 struct segment{
10 double l,r,h;
11 int cnt;
12 }ss[2005];
13
14 double pos[2005];
15 int n,k;
16 struct segTree{
17 int l,r,col;
18 double v;
19 int callmid(){ return (l + r) >> 1; }
20 }st[10000];
21
22 bool cmp(segment a, segment b){
23 return a.h < b.h;
24 }
25
26 void bd(int l,int r,int idx){
27 int mid;
28 st[idx].l = l;
29 st[idx].r = r;
30 st[idx].v = 0;
31 st[idx].col = 0;
32 if(l == r) return ;
33 mid = st[idx].callmid();
34 bd(l,mid,LL(idx));
35 bd(mid+1,r,RR(idx));
36 }
37
38 void fix(int idx){
39 if(st[idx].col > 1 ){
40 st[idx].v = pos[st[idx].r+1] - pos[st[idx].l];
41 }
42 else if(st[idx].l == st[idx].r) {
43 st[idx].v = 0;
44 }
45 else if(st[idx].col != 0){
46 st[LL(idx)].col += st[idx].col;
47 st[RR(idx)].col += st[idx].col;
48 st[idx].col = 0;
49 fix(LL(idx));
50 fix(RR(idx));
51 st[idx].v = st[LL(idx)].v + st[RR(idx)].v;
52 }
53 else {
54 st[idx].v = st[LL(idx)].v + st[RR(idx)].v;
55 }
56 }
57
58 void update(int l,int r,int c,int idx){
59 int mid;
60 if(st[idx].l >= l && st[idx].r <= r){
61 st[idx].col += c;
62 fix(idx);
63 return;
64 }
65
66 mid = st[idx].callmid();
67 if(l <= mid) update(l,r,c,LL(idx));
68 if(r > mid) update(l,r,c,RR(idx));
69
70 fix(idx);
71 }
72
73 int Bin(double x,int r){
74 int l,mid;
75 l = 0;
76 while(l <= r){
77 mid = (l + r) >> 1;
78 if(pos[mid] == x) return mid;
79 if(pos[mid] < x){
80 l = mid + 1;
81 }
82 else {
83 r = mid - 1;
84 }
85 }
86 return -1;
87 }
88
89 int main(){
90 // freopen("c:/aaa.txt","r",stdin);
91
92 int i,T;
93 double a,b,c,d,l,r,ans;
94 scanf("%d",&T);
95 while(T--){
96 scanf("%d",&n);
97 for(i=0;i<n;++i){
98 scanf("%lf %lf %lf %lf",&a, &b, &c, &d);
99 pos[2*i] = a;
100 pos[2*i+1] = c;
101 ss[2*i].l = ss[2*i+1].l = a;
102 ss[2*i].r = ss[2*i+1].r = c;
103 ss[2*i].h = b;
104 ss[2*i].cnt = 1;
105 ss[2*i+1].h = d;
106 ss[2*i+1].cnt = -1;
107 }
108
109 sort(ss,ss + 2*n,cmp);
110 sort(pos,pos + 2*n);
111
112
113 k = 0;
114 for(i=0;i<2*n;++i){
115 if(i==0 || pos[i]!=pos[i-1])
116 pos[k++]=pos[i];
117 }
118
119 bd(0,k-1,1);
120 ans=0;
121 for(i=0;i<2*n;++i){
122 l = Bin(ss[i].l,k-1);
123 r = Bin(ss[i].r,k-1) - 1;
124 update(l,r,ss[i].cnt,1);
125 ans += st[1].v * (ss[i+1].h - ss[i].h);
126 }
127
128 printf("%.2lf\n",ans);
129 }
130 return 0;
131 }
132

12.Hdoj 1828 Picture

代码
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #define LL(x) ((x)<<1)
5 #define RR(x) ((x)<<1|1)
6 using namespace std;
7
8 struct segment{
9 int l,r,h,cnt;
10 }ss[10005];
11 struct segTree{
12 int l,r,col,num;
13 int lv,rv,v;
14 int callmid() { return (l + r) >> 1; }
15 int dis() { return (r - l + 1); }
16 }st[80000];
17 int n;
18 bool cmp(segment a,segment b){
19 return a.h < b.h;
20 }
21
22 void bd(int l,int r,int idx){
23 int mid;
24 st[idx].l = l;
25 st[idx].r = r;
26 st[idx].lv = st[idx].rv = 0;
27 st[idx].col = st[idx].num = st[idx].v = 0;
28 if(l == r) return ;
29 mid = st[idx].callmid();
30 bd(l,mid,LL(idx));
31 bd(mid+1,r,RR(idx));
32 }
33
34 void fix(int idx){
35 if(st[idx].col){
36 st[idx].lv = st[idx].rv = 1;
37 st[idx].v = st[idx].dis();
38 st[idx].num = 1;
39 }
40 else if(st[idx].l == st[idx].r){
41 st[idx].lv = st[idx].rv = 0;
42 st[idx].v = 0;
43 st[idx].num = 0;
44 }
45 else {
46 int ll,rr;
47 ll = LL(idx);
48 rr = RR(idx);
49 st[idx].lv = st[ll].lv;
50 st[idx].rv = st[rr].rv;
51 st[idx].v = st[ll].v + st[rr].v;
52 st[idx].num = st[ll].num + st[rr].num - (st[ll].rv&st[rr].lv);
53 }
54 }
55
56
57 void update(int l,int r,int c,int idx){
58 int mid;
59 if(st[idx].l >= l && st[idx].r <= r){
60 st[idx].col += c;
61 fix(idx);
62 return ;
63 }
64 mid = st[idx].callmid();
65 if(l <= mid) update(l,r,c,LL(idx));
66 if(r > mid) update(l,r,c,RR(idx));
67 fix(idx);
68 }
69
70 int main(){
71 // freopen("c:/aaa.txt","r",stdin);
72 int i;
73 int a,b,c,d;
74 int l,r;
75 while(scanf("%d",&n)!=EOF){
76 if(n == 0){
77 printf("0\n");
78 continue;
79 }
80
81 l = 10000;
82 r = -10000;
83 for(i=0;i<n;++i){
84 scanf("%d %d %d %d", &a, &b, &c, &d);
85 if(a < l) l = a;
86 if(c > r) r = c;
87 ss[2*i].l = ss[2*i+1].l = a;
88 ss[2*i].r = ss[2*i+1].r = c;
89 ss[2*i].h = b;
90 ss[2*i+1].h = d;
91 ss[2*i].cnt = 1;
92 ss[2*i+1].cnt = -1;
93 }
94
95 sort(ss,ss+2*n,cmp);
96 bd(l,r-1,1);
97 int ans = 0,temp = 0;
98 for(i=0;i<2*n;++i){
99 update(ss[i].l,ss[i].r-1,ss[i].cnt,1);
100 ans += 2 * st[1].num * (ss[i+1].h - ss[i].h);
101 ans += abs(st[1].v - temp);
102 temp = st[1].v;
103 }
104
105 printf("%d\n",ans);
106 }
107 return 0;
108 }
109

13.hdoj 3308 LCIS

点更新,区间查询最长连续递增序列长度。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

#define LL(x)  ((x)<<1)
#define RR(x)  ((x)<<1|1)

struct segTree {
	int l, r;
	int la, lv, ra, rv, v;
	int callmid() { return (r + l) >> 1; }
}st[800000];


int n, m, num[200005];


int mymax(int a1, int a2, int a3, int a4, int a5) {
	int a[6];
	a[0] = a1; a[1] = a2; a[2] = a3;
	a[3] = a4; a[4] = a5;
	sort(a, a+5);
	return a[4];
}

int threeMax(int a, int b, int c) {
	a = a > b ? a : b;
	a = a > c ? a : c;
	return a;
}

void bd(int l, int r, int idx) {
	int mid;
	st[idx].l = l;
	st[idx].r = r;
	if(l == r) {
		st[idx].la = st[idx].ra = num[l];
		st[idx].lv = st[idx].rv = st[idx].v = 1;
		return;
	}
	
	mid = (l + r) >> 1;
	bd(l, mid, LL(idx));
	bd(mid + 1, r, RR(idx));
	st[idx].la = st[LL(idx)].la;
	st[idx].ra = st[RR(idx)].ra;
	st[idx].lv = st[LL(idx)].lv;
	st[idx].rv = st[RR(idx)].rv;
	if(st[LL(idx)].lv == (st[LL(idx)].r - st[LL(idx)].l + 1) && st[LL(idx)].ra < st[RR(idx)].la) 
		st[idx].lv += st[RR(idx)].lv;
	if(st[RR(idx)].rv == (st[RR(idx)].r - st[RR(idx)].l + 1) && st[LL(idx)].ra < st[RR(idx)].la)
		st[idx].rv += st[LL(idx)].rv;
	int tempv;
	if(st[LL(idx)].ra < st[RR(idx)].la) tempv = st[LL(idx)].rv + st[RR(idx)].lv;
	else tempv = 0;
	st[idx].v = mymax(tempv, st[idx].lv, st[idx].rv, st[LL(idx)].v, st[RR(idx)].v);
}



void update(int a, int b, int idx) {
	int l, r, mid;
	if(st[idx].l >= a && st[idx].r <= a) {
		st[idx].la = st[idx].ra = b;
		return ;
	}

	mid = st[idx].callmid();
	if(a <= mid) update(a, b, LL(idx));
	else update(a, b, RR(idx));

	l = LL(idx);
	r = RR(idx);
	st[idx].la = st[l].la;
	st[idx].ra = st[r].ra;
	st[idx].lv = st[l].lv;
	st[idx].rv = st[r].rv;
	if(st[l].lv == (st[l].r - st[l].l + 1) && st[l].ra < st[r].la) 
		st[idx].lv += st[r].lv;
	if(st[r].rv == (st[r].r - st[r].l + 1) && st[l].ra < st[r].la)
		st[idx].rv += st[l].rv;
	int tempv;
	if(st[l].ra < st[r].la) tempv = st[l].rv + st[r].lv;
	else tempv = 0;
	st[idx].v = mymax(tempv, st[idx].lv, st[idx].rv, st[l].v, st[r].v);
}



int query(int a, int b, int idx) {
	int mid;
	if(st[idx].l >= a && st[idx].r <= b) return st[idx].v;
	mid = st[idx].callmid();
	if(b <= mid) return query(a, b, LL(idx));
	else if(a > mid) return query(a, b, RR(idx));
	else {
		int tempv, a1, a2;
		if(st[LL(idx)].ra < st[RR(idx)].la){
			if(st[LL(idx)].rv > mid - a + 1) a1 = mid - a + 1;
			else a1 = st[LL(idx)].rv;
			if(st[RR(idx)].lv > b - mid) a2 = b - mid;
			else a2 = st[RR(idx)].lv;
			tempv = a1 + a2;
		}
		else tempv = 0;
		return threeMax(tempv, query(a, mid, LL(idx)), query(mid+1, b, RR(idx)));
	}
}
	


void init() {
	int i, j;
	scanf("%d %d", &n, &m);
	for(i=0; i<n; ++i) scanf("%d", &num[i]);
	bd(0, n-1, 1);
}


void solve() {
	int i, a, b;
	char ch[5];
	for(i=0; i<m; ++i) {
		scanf("%s %d %d", &ch, &a, &b);
		if(ch[0] == 'U') update(a, b, 1);
		else if(ch[0] == 'Q') printf("%d\n", query(a, b, 1));
	}
}


int main() {
//	freopen("c:/aaa.txt", "r", stdin);
	int T;
	scanf("%d", &T);
	while(T --) {
		init();
		solve();
	}
	return 0;
}

14.zstuoj 3125 Happy Children's Day

#include <iostream>
#define LL(x)  ((x)<<1)
#define RR(x)  ((x)<<1|1)
using namespace std;


struct segTree{
	int l,r;
	int maxv,pos,col;
	int callmid(){ return (l + r) >> 1; }
}st[500000];

struct Node{
	int pos,v;
};

int n;


void bd(int l,int r,int idx){
	int mid;
	st[idx].l = l;
	st[idx].r = r;
	st[idx].maxv = 0;
	st[idx].pos = l;
	st[idx].col = 0;
	if(l == r){ return; }
	mid = st[idx].callmid();
	bd(l,mid,LL(idx));
	bd(mid+1,r,RR(idx));
}



void update(int l,int r,int c,int idx){
	int mid,ll,rr;
	if(st[idx].l >= l && st[idx].r <= r){
		st[idx].maxv += c;
		st[idx].col += c;
		return;
	}

	mid = st[idx].callmid();
	ll = LL(idx);
	rr = RR(idx);

	if(st[idx].col){
		st[ll].col += st[idx].col;
		st[ll].maxv += st[idx].col;
		st[rr].col += st[idx].col;
		st[rr].maxv += st[idx].col;
		st[idx].col = 0;
	}
		
	if(l <= mid) update(l,r,c,ll);
	if(r > mid) update(l,r,c,rr);
	
	if(st[ll].maxv >= st[rr].maxv){
		st[idx].maxv = st[ll].maxv;
		st[idx].pos = st[ll].pos;
	}else {
		st[idx].maxv = st[rr].maxv;
		st[idx].pos = st[rr].pos;
	}
}



Node mymax(Node nd1, Node nd2){
	if(nd1.v >= nd2.v){
		return nd1;
	}else {
		return nd2;
	}
}



Node query(int l,int r,int idx){
	int mid,ll,rr;
	Node nd;
	if(st[idx].l == l && st[idx].r == r){
		nd.pos = st[idx].pos;
		nd.v = st[idx].maxv;
		return nd;
	}

	ll = LL(idx);
	rr = RR(idx);
	mid = st[idx].callmid();

	if(st[idx].col){
		st[ll].col += st[idx].col;
		st[ll].maxv += st[idx].col;
		st[rr].col += st[idx].col;
		st[rr].maxv += st[idx].col;
		st[idx].col = 0;
	}
	
	if(r <= mid){
		return query(l,r,ll);
	}else if(l > mid){
		return query(l,r,rr);
	}else{
		return mymax( query(l,mid,ll), query(mid+1,r,rr) );
	}
}
	

void Read(int &x){
	char ch;
	x = 0;
	ch = getchar();
	while( !(ch >= '0' && ch <= '9') ) ch = getchar();
	while( (ch >= '0' && ch <= '9') ){
		x = x * 10 + ch - '0';
		ch = getchar();
	}
}

void Output(int x){
	char ch;
	if(x/10 >0){
		Output(x/10);
	}
	ch = (x % 10) + '0';
	putchar(ch);
}



int main(){
//	freopen("c:/aaa.txt","r",stdin);
	int m,l,r,c;
	Node nd;
	char ch;
	while(1){
		Read(n);
		Read(m);
		if(n ==0 && m == 0) break;
		bd(1,n,1);
		while(m--){
			ch = getchar();
			if(ch == 'I'){
				Read(l);
				Read(r);
				Read(c);
			//	scanf("%d%d%d",&l,&r,&c);
				update(l,r,c,1);
			}else{
				Read(l);
				Read(r);
			//	scanf("%d%d",&l,&r)
				nd = query(l,r,1);
				Output(nd.v);
				putchar('\n');
			//	printf("%d\n",nd.v);
				update(nd.pos,nd.pos,-nd.v,1);
			}
		}
	}
	return 0;
}

15.hdoj 3577 Fast Arrangement

区间更新,区间查询。区间更新时设置一变量,表示父节点对子节点的影响量。这样子区间的值就等于子区间记录的值加上这个影响量。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define LL(x)  ((x)<<1)
#define RR(x)  ((x)<<1|1)

struct segTree {
	int l, r, v, lnc;  //lnc为父节点对子节点的影响量,v为节点的值
	int callmid() { return (l + r) >> 1; }
}st[5000000];


struct Node {
	int a, b;
}ns[100002];

int n, m, bigv;

//io外挂
void Read(int &x) {
	char ch;
	x = 0;
	ch = getchar();
	while(!(ch >= '0' && ch <= '9')) ch = getchar();
	while(ch >= '0' && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
}



int max(int a, int b) { return a > b ? a : b; }


void bd(int l, int r, int idx) {
	int mid;
	st[idx].l = l;
	st[idx].r = r;
	st[idx].v = st[idx].lnc = 0;
	if(l == r) return;
	
	mid = st[idx].callmid();
	bd(l, mid, LL(idx));
	bd(mid+1, r, RR(idx));
}



int query(int l, int r, int idx) {
	int mid;
	if(st[idx].l >= l && st[idx].r <= r) {
		return st[idx].v;
	}

	mid = st[idx].callmid();
	if(r <= mid) 
		return query(l, r, LL(idx)) + st[idx].lnc;
	else if(l > mid) 
		return query(l, r, RR(idx)) + st[idx].lnc;
	else 
		return max(query(l, mid, LL(idx)), query(mid+1, r, RR(idx))) + st[idx].lnc;
}



void update(int l, int r, int idx) {
	int mid;
	if(st[idx].l >= l && st[idx].r <= r) {
		st[idx].v ++;
        st[idx].lnc ++;
		return ;
	}

	mid = st[idx].callmid();
	if(r <= mid) update(l, r, LL(idx));
	else if(l > mid) update(l, r, RR(idx));
	else {
		update(l, mid, LL(idx));
		update(mid+1, r, RR(idx));
	}

	st[idx].v = max(st[LL(idx)].v, st[RR(idx)].v) + st[idx].lnc;;
}



int main() {
//	freopen("c:/aaa.txt", "r", stdin);
	int T, ca = 1, i;
	scanf("%d", &T);
	while(T -- ) {
		printf("Case %d:\n", ca ++);
		Read(n);
		Read(m);
		bigv = 0;
		for(i=1; i<=m; ++i) {
			Read(ns[i].a);
			Read(ns[i].b);
			if(ns[i].a > bigv) bigv = ns[i].a;
			if(ns[i].b > bigv) bigv = ns[i].b;
		}
		bd(1, bigv, 1);
		for(i=1; i<=m; ++i) {
			if(query(ns[i].a, ns[i].b - 1, 1) < n) {
				printf("%d ", i);
				update(ns[i].a, ns[i].b - 1, 1);
			}
		}
		printf("\n\n");
	}
	return 0;
}
	

 16.hdoj 3486 Interviewe

二分枚举切割后小组的数目,然后线段树求解。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

#define LL(x)   ((x)<<1)
#define RR(x)   ((x)<<1|1)

struct segTree {
    int l, r, v;
}st[800000];

const int maxn = 200002;
int n, limit, sum;


int max(int a, int b) { return a > b ? a : b; }


void bd(int l, int r, int idx) {
    int mid;
    st[idx].l = l;
    st[idx].r = r;
    st[idx].v = 0;
    if(l == r) return;
    
    mid = (l + r) >> 1;
    bd(l, mid, LL(idx));
    bd(mid + 1, r, RR(idx));
}



void update(int a, int b, int idx) {
    int mid;
    if(st[idx].l == a && st[idx].r == a) {
        st[idx].v = b;
        return;
    }

    mid = (st[idx].l + st[idx].r) >> 1;
    if(a <= mid) update(a, b, LL(idx));
    else update(a, b, RR(idx));

    if(b > st[idx].v) st[idx].v = b;
}



int query(int l, int r, int idx) {
    int mid;
    if(st[idx].l >= l && st[idx].r <= r) {
        return st[idx].v;
    }

    mid = (st[idx].l + st[idx].r) >> 1;
    if(r <= mid) {
        return query(l, r, LL(idx));
    } else if(l > mid) {
        return query(l, r, RR(idx));
    } else {
        return max(query(l, mid, LL(idx)), query(mid+1, r, RR(idx)));
    }
}




void init() {
    int i, a;
    sum = 0;
    bd(1, n, 1);
    for(i=1; i<=n; ++i) {
        scanf("%d", &a);
        sum += a;
        update(i, a, 1);
    }
}



bool judge(int zs) {
    int m, i, ssum = 0;
    m = n/zs;
    for(i=1; i<=zs; ++i) {
        int head, tail;
        head = (i - 1) * m + 1;
        tail = head + m - 1;
        ssum += query(head, tail, 1);
    }
    return (ssum > limit);
}



int solve() {
    int l, r, mid, ans;
    if(sum <= limit) return -1;
    l = 1;
    r = n;
    ans = -1;
    while(l <= r) {
        mid = (l + r) >> 1;
        if(judge(mid)) {
            ans = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return ans;
}
        

int main() {
//    freopen("c:/aaa.txt", "r", stdin);
    while(scanf("%d %d", &n, &limit) == 2) {
        if(n == -1 && limit == -1) break;
        init();
        printf("%d\n", solve());
    }
    return 0;
}

 17.hdoj3397 Sequence operation

线段树大综合,这题太NB了,自己写得几乎要吐血。网上看到某牛写得超级犀利的代码,代码如下,无限膜拜~~

update()和down()用得相当犀利呀。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define LL(x)  ((x)<<1)
#define RR(x)  ((x)<<1|1)


const int maxn = 100002;
int n, m, num[maxn];

struct segTree {
	int left, right, mid, len;
	int left0, right0, max0, count0;
	int left1, right1, max1, count1;
	bool flag0, flag1, flagchg;
}st[4*maxn];


//int max(int a, int b) { return a > b ? a : b; } 不能定义,编译器包含max和min,如果自己又定义,就会产生错误,在这个地方WA了几个小时。汗。。。
//int min(int a, int b) { return a < b ? a : b; } 要定义就取个别的名字,去注释后,而其要用G++提交。。。

void update(int idx) {
	int ll, rr, mid;
	ll = LL(idx); 
	rr = RR(idx);
	st[idx].count0 = st[ll].count0 + st[rr].count0;
	st[idx].count1 = st[ll].count1 + st[rr].count1;
	st[idx].left0 = (st[ll].left0 == st[ll].len) ? st[ll].left0 + st[rr].left0 : st[ll].left0;
	st[idx].left1 = (st[ll].left1 == st[ll].len) ? st[ll].left1 + st[rr].left1 : st[ll].left1;
	st[idx].right0 = (st[rr].right0 == st[rr].len) ? st[rr].right0 + st[ll].right0 : st[rr].right0;
	st[idx].right1 = (st[rr].right1 == st[rr].len) ? st[rr].right1 + st[ll].right1 : st[rr].right1;
	st[idx].max0 = max(st[ll].right0 + st[rr].left0, max(st[ll].max0, st[rr].max0));
	st[idx].max1 = max(st[ll].right1 + st[rr].left1, max(st[ll].max1, st[rr].max1));
}

	

void bd(int l, int r, int idx) {
	st[idx].left = l;
	st[idx].right = r;
	st[idx].mid = (l + r) >> 1;
	st[idx].len = r - l + 1;
	st[idx].flag0 = st[idx].flag1 = st[idx].flagchg = 0;
	if(l == r) {
		st[idx].left0 = st[idx].right0 = st[idx].max0 = st[idx].count0 = !num[l];
		st[idx].left1 = st[idx].right1 = st[idx].max1 = st[idx].count1 =  num[l];
		return;
	}

	bd(l, st[idx].mid, LL(idx));
	bd(st[idx].mid+1, r, RR(idx));
	update(idx);
}
		



void fill0(int idx) {
	st[idx].left0 = st[idx].right0 = st[idx].max0 = st[idx].count0 = st[idx].len;
	st[idx].left1 = st[idx].right1 = st[idx].max1 = st[idx].count1 = 0;
	st[idx].flag0 = 0;
	if(st[idx].left == st[idx].right)  return;
	st[LL(idx)].flag0 = st[RR(idx)].flag0 = 1;
	st[LL(idx)].flag1 = st[RR(idx)].flag1 = 0;
	st[LL(idx)].flagchg = st[RR(idx)].flagchg = 0;
}


void fill1(int idx) {
	st[idx].left0 = st[idx].right0 = st[idx].max0 = st[idx].count0 = 0;
	st[idx].left1 = st[idx].right1 = st[idx].max1 = st[idx].count1 = st[idx].len;
	st[idx].flag1 = 0;
	if(st[idx].left == st[idx].right)  return;
	st[LL(idx)].flag0 = st[RR(idx)].flag0 = 0;
	st[LL(idx)].flag1 = st[RR(idx)].flag1 = 1;
	st[LL(idx)].flagchg = st[RR(idx)].flagchg = 0;
}



void fillchg(int idx) {
	swap(st[idx].left0, st[idx].left1);
	swap(st[idx].right0, st[idx].right1);
	swap(st[idx].max0, st[idx].max1);
	swap(st[idx].count0, st[idx].count1);
	st[idx].flagchg = 0;
	if(st[idx].right == st[idx].left) return;
	st[LL(idx)].flagchg ^= 1; 
	st[RR(idx)].flagchg ^= 1;
}




void down(int idx) {
	if(st[idx].flag0) fill0(idx);
	if(st[idx].flag1) fill1(idx);
	if(st[idx].flagchg) fillchg(idx);
}



void change(int op, int l, int r, int idx) {
	down(idx);
	if(st[idx].left >= l && st[idx].right <= r) {
		if(op == 0) st[idx].flag0 = 1;
		else if(op == 1) st[idx].flag1 = 1;
		else st[idx].flagchg^=1;
		down(idx);
		return;
	}

	if(r <= st[idx].mid) change(op, l, r, LL(idx));
	else if(l > st[idx].mid) change(op, l, r, RR(idx));
	else {
		change(op, l, st[idx].mid, LL(idx));
		change(op, st[idx].mid+1, r, RR(idx));
	}
	down(LL(idx)); down(RR(idx));
	update(idx);
}


int countone(int l, int r, int idx) {
	down(idx);
	if(st[idx].left >= l && st[idx].right <= r) return st[idx].count1;

	if(r <= st[idx].mid) return countone(l, r, LL(idx));
	else if(l > st[idx].mid) return countone(l, r, RR(idx));
	else return countone(l, st[idx].mid, LL(idx)) + countone(st[idx].mid+1, r, RR(idx));
}


int countlone(int l, int r, int i) {
	down(i);
	if(st[i].left >= l && st[i].right <= r) return st[i].max1;

	if(r <= st[i].mid) return countlone(l, r, LL(i));
	else if(l > st[i].mid) return countlone(l, r, RR(i));
//	else return max(max(countlone(l, st[i].mid, LL(i)), countlone(st[i].mid+1, r, RR(i))), st[LL(i)].right1+st[RR(i)].left1);
	 else return max(max(countlone(l,st[i].mid,2*i), countlone(st[i].mid+1,r,2*i+1)),  
         min(st[2*i].right1,st[i].mid-l+1)+min(st[2*i+1].left1,r-st[i].mid));  
}



int main() {
//	freopen("c:/aaa.txt", "r", stdin);
	int T, i, op, l, r;
	scanf("%d", &T);
	while(T--) {
		scanf("%d %d", &n, &m);
		for(i=0; i<n; ++i) {
			scanf("%d", &num[i]);
		}
		bd(0, n-1, 1);
		while(m--) {
			scanf("%d %d %d", &op, &l, &r);
			if(op <= 2) change(op, l, r, 1);
			else if(op == 3) printf("%d\n", countone(l, r, 1));
			else printf("%d\n", countlone(l, r, 1));
		}
	}
	return 0;
}

 18.hdoj 1823 Luck and Love

二维线段树,更新二维点。

#include <iostream>
#include <cstdio>
using namespace std;

#define LL(x) ((x)<<1)
#define RR(x) ((x)<<1|1)


struct sub_segTree {
    int l, r, v;
    int mid() { return (l + r) >> 1; }
};

struct segTree {
    int l, r;
    sub_segTree st[4005];
    int mid() { return (l + r) >> 1; }
}st[405];


void bd2( sub_segTree st[], int l, int r, int idx ) {
    st[idx].l = l; 
    st[idx].r = r;
    st[idx].v = -1;
    if( l == r ) return ;
    int mid = st[idx].mid();
    bd2( st, l, mid, LL(idx) );
    bd2( st, mid+1, r, RR(idx) );
}


void bd( int l, int r, int idx ) {
    st[idx].l = l; st[idx].r = r;
    bd2( st[idx].st, 0, 1000, 1 );
    if( l == r ) return ;
    int mid = st[idx].mid();
    bd( l, mid, LL(idx) );
    bd( mid+1, r, RR(idx) );
}


void update2( sub_segTree st[], int a, int v, int idx ) {
    if( st[idx].l == st[idx].r ) {
        st[idx].v = max( st[idx].v, v );
        return;
    }

    int mid = st[idx].mid();
    if( a <= mid ) update2( st, a, v, LL(idx) );
    else update2( st, a, v, RR(idx) );
    st[idx].v = max( st[LL(idx)].v, st[RR(idx)].v );
}


void update( int h, int a, int v, int idx ) {
    update2( st[idx].st, a, v, 1 );
    if( st[idx].l == st[idx].r) return;
    int mid = st[idx].mid();
    if( h <= mid ) update( h, a, v, LL(idx) );
    else update( h, a, v, RR(idx) );
}


int query2( sub_segTree st[], int l2, int r2, int idx ) {
    if( st[idx].l >= l2 && st[idx].r <= r2 ) return st[idx].v;
    int mid = st[idx].mid();
    if( r2 <= mid ) return query2( st, l2, r2, LL(idx) );
    else if( l2 > mid ) return query2( st, l2, r2, RR(idx) );
    else return max( query2( st, l2, mid, LL(idx) ), query2( st, mid+1, r2, RR(idx) ) );
}

int query( int l1, int r1, int l2, int r2, int idx ) {
    if( st[idx].l >= l1 && st[idx].r <= r1 ) {
        return query2( st[idx].st, l2, r2, 1 );
    }
    int mid = st[idx].mid();
    if( r1 <= mid ) return query( l1, r1, l2, r2, LL(idx) );
    else if( l1 > mid ) return query( l1, r1, l2, r2, RR(idx) );
    else return max( query( l1, mid, l2, r2, LL(idx) ), query( mid+1, r1, l2, r2, RR(idx) ) );
}


int main() {
//    freopen("c:/aaa.txt", "r", stdin);
    int n, H, i, j, l1, r1, ans;
    double A, L, l2, r2;
    char ch[5];
    while( scanf("%d", &n) == 1 && n ) {
        bd( 100, 200, 1 );
        while( n-- ) {
            scanf( "%s", ch );
            if( ch[0] == 'I' ) {
                scanf( "%d %lf %lf", &H, &A, &L );
                update( H, (int)(A*10), (int)(L*10), 1 );
            } else {
                scanf( "%d %d %lf %lf", &l1, &r1, &l2, &r2 );
                if( l1 > r1 ) swap( l1, r1 );
                if( l2 > r2 ) swap( l2, r2 );
                ans = query(l1, r1, (int)(l2*10), (int)(r2*10), 1);
                if(ans < 0) puts("-1");
                else printf("%.1lf\n", ans/10.0);
            }    
        }
    }
    return 0;
}


posted on 2010-11-12 13:14  CrazyAC  阅读(1040)  评论(0编辑  收藏  举报