线段树专辑
这段时间研究研究线段树。
hh大牛的线段树专辑http://www.notonlysuccess.com/?p=59
代码
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
代码
1 #include <iostream>
2 #include <cstdio>
3 #define LL(x) ((x)<<1)
4 #define RR(x) ((x)<<1|1)
5 using namespace std;
6 int n,m;
7 int num[200001];
8
9 struct segTree{
10 int r,l,v;
11 int callmid(){ return (r+l)/2;}
12 }st[600000];
13 int max(int a,int b){
14 if(a>b) return a;
15 else return b;
16 }
17
18 int bd(int l,int r,int idx){
19 int mid;
20 st[idx].l=l;
21 st[idx].r=r;
22 if(l==r){return st[idx].v=num[l];}
23 mid=(l+r)/2;
24 return st[idx].v=max(bd(l,mid,LL(idx)),bd(mid+1,r,RR(idx)));
25 }
26
27 int query(int l,int r,int idx){
28 int mid;
29 if(st[idx].l==l && st[idx].r==r){
30 return st[idx].v;
31 }
32 mid=st[idx].callmid();
33 if(r<=mid){
34 return query(l,r,LL(idx));
35 }
36 else if(l>mid){
37 return query(l,r,RR(idx));
38 }
39 else {
40 return max(query(l,mid,LL(idx)),query(mid+1,r,RR(idx)));
41 }
42 }
43 void update(int a,int b,int idx){
44 int mid;
45 if(st[idx].v<b) st[idx].v=b;
46 if(st[idx].l==st[idx].r) return ;
47 mid=st[idx].callmid();
48 if(a<=mid){
49 update(a,b,LL(idx));
50 }
51 else{
52 update(a,b,RR(idx));
53 }
54 }
55 int main(){
56 // freopen("c:/aaa.txt","r",stdin);
57 int i,a,b;
58 char ch[10];
59 while(scanf("%d%d",&n,&m)!=EOF){
60 for(i=1;i<=n;++i){
61 scanf("%d",&num[i]);
62 }
63 bd(1,n,1);
64 for(i=1;i<=m;++i){
65 scanf("%s%d%d",ch,&a,&b);
66 switch(ch[0]){
67 case 'Q':
68 printf("%d\n",query(a,b,1));
69 break;
70 case 'U':
71 update(a,b,1);
72 break;
73 }
74 }
75 }
76 return 0;
77 }
78
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; }
区间更新,区间查询。区间更新时设置一变量,表示父节点对子节点的影响量。这样子区间的值就等于子区间记录的值加上这个影响量。
#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; }
二分枚举切割后小组的数目,然后线段树求解。
#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; }
二维线段树,更新二维点。
#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; }