线段树

参考资料:http://www.notonlysuccess.com/index.php/segment-tree-complete/

hdu1166

题意:对于n(n≤500000),操作有两种:①任意更改某个点的值②求任意区间的和

View Code
 1 #include <stdio.h>
 2 const int N=50005<<2;
 3 int sum[N];
 4 int T,n;
 5 ///rt表示当前子树的根(root),也就是当前所在的结点
 6 void PushUP(int rt){
 7     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 8 }
 9 void build(int left,int right,int rt){
10     if(left==right) {
11         scanf("%d",&sum[rt]);
12         return ;
13     }
14     int mid=(left+right)>>1;
15     build(left,mid,rt<<1);
16     build(mid+1,right,rt<<1|1);
17     PushUP(rt);
18 }
19 void update(int p,int add,int left,int right,int rt){
20     if(left==right) {
21         sum[rt]+=add;
22         return ;
23     }
24     int mid=(left+right)>>1;
25     if(p<=mid) update(p,add,left,mid,rt<<1);
26     else update(p,add,mid+1,right,rt<<1|1);
27     PushUP(rt);
28 }
29 int query(int L,int R,int left,int right,int rt){
30     if(L<=left&&right<=R){
31         return sum[rt];
32     }
33     int mid=(left+right)>>1;
34     int ret=0;
35     if(L<=mid) ret+=query(L,R,left,mid,rt<<1);
36     if(R>mid) ret+=query(L,R,mid+1,right,rt<<1|1);
37     return ret;
38 }
39 int main(){
40     int i,j,cas=1;
41     char ch[10];
42     while(scanf("%d",&T)!=EOF)
43     while(T--){
44         scanf("%d",&n);
45         build(1,n,1);
46         printf("Case %d:\n",cas++);
47         while(scanf("%s",ch)){
48             if(ch[0]=='E') break;
49             scanf("%d%d",&i,&j);
50             if(ch[0]=='Q') printf("%d\n",query(i,j,1,n,1));
51             else if(ch[0]=='S') update(i,-j,1,n,1);
52             else update(i,j,1,n,1);
53         }
54     }
55     return 0;
56 }

hdu1754

题意:区间求最值

View Code
 1 #include <stdio.h>
 2 const int N=200005<<2;
 3 int Max[N];
 4 int q,n;
 5 ///rt表示当前子树的根(root),也就是当前所在的结点
 6 int max(int a,int b){return a>b?a:b;}
 7 void PushUP(int rt){
 8     Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
 9 }
10 void build(int left,int right,int rt){
11     if(left==right) {
12         scanf("%d",&Max[rt]);
13         return ;
14     }
15     int mid=(left+right)>>1;
16     build(left,mid,rt<<1);
17     build(mid+1,right,rt<<1|1);
18     PushUP(rt);
19 }
20 void update(int p,int sc,int left,int right,int rt){
21     if(left==right) {
22         Max[rt]=sc;
23         return ;
24     }
25     int mid=(left+right)>>1;
26     if(p<=mid) update(p,sc,left,mid,rt<<1);
27     else update(p,sc,mid+1,right,rt<<1|1);
28     PushUP(rt);
29 }
30 int query(int L,int R,int left,int right,int rt){
31     if(L<=left&&right<=R){
32         return Max[rt];
33     }
34     int mid=(left+right)>>1;
35     int ret=0;
36     if(L<=mid) ret=max(ret,query(L,R,left,mid,rt<<1));
37     if(R>mid) ret=max(ret,query(L,R,mid+1,right,rt<<1|1));
38     return ret;
39 }
40 int main(){
41     int i,j;
42     char ch[10];
43     while(scanf("%d%d",&n,&q)!=EOF){
44         build(1,n,1);
45         while(q--){
46             scanf("%s",ch);
47             scanf("%d%d",&i,&j);
48             if(ch[0]=='Q') printf("%d\n",query(i,j,1,n,1));
49             else update(i,j,1,n,1);
50         }
51     }
52     return 0;
53 }

hrbustoj1752

题意:求最值,输出下角标

View Code
 1 #include <stdio.h>
 2 const int N=100005<<2;
 3 struct T{
 4     int idx;
 5     int Max;
 6 }t[N];
 7 int q,n;
 8 ///rt表示当前子树的根(root),也就是当前所在的结点
 9 T max(T t1,T t2){
10     if(t1.Max!=t2.Max) return t1.Max>t2.Max?t1:t2;
11     else return t1.idx>t2.idx?t1:t2;
12 }
13 void PushUP(int rt){
14     t[rt]=max(t[rt<<1],t[rt<<1|1]);
15 }
16 void build(int left,int right,int rt){
17     if(left==right) {
18         scanf("%d",&t[rt].Max);
19         t[rt].idx=left;
20         return ;
21     }
22     int mid=(left+right)>>1;
23     build(left,mid,rt<<1);
24     build(mid+1,right,rt<<1|1);
25     PushUP(rt);
26 }
27 void update(int p,int sc,int left,int right,int rt){
28     if(left==right) {
29         t[rt].Max=sc;
30         return ;
31     }
32     int mid=(left+right)>>1;
33     if(p<=mid) update(p,sc,left,mid,rt<<1);
34     else update(p,sc,mid+1,right,rt<<1|1);
35     PushUP(rt);
36 }
37 T query(int L,int R,int left,int right,int rt){
38     if(L<=left&&right<=R){
39         return t[rt];
40     }
41     int mid=(left+right)>>1;
42     T ret;ret.Max=0;
43     if(L<=mid) ret=max(ret,query(L,R,left,mid,rt<<1));
44     if(R>mid) ret=max(ret,query(L,R,mid+1,right,rt<<1|1));
45     return ret;
46 }
47 int main(){
48     int i,j;
49     char ch[10];
50     while(scanf("%d",&n)!=EOF){
51         build(1,n,1);
52         scanf("%d",&q);
53         while(q--){
54             scanf("%s",ch);
55             if(ch[0]=='Q') {
56                 T tmp=query(1,n,1,n,1);
57                 printf("%d %d\n",tmp.idx,tmp.Max);
58             }
59             else {
60                 scanf("%d%d",&i,&j);
61                 update(i,j,1,n,1);
62             }
63         }
64         puts("");
65     }
66     return 0;
67 }

这道题或者用堆,或者用优先队列

View Code
 1 #include <stdio.h>
 2 #include <queue>
 3 #include <iostream>
 4 using namespace std;
 5 struct info{
 6     int idx;
 7     int key;
 8     bool operator < (const info &a) const {
 9         if(a.key!=key) return a.key>key;
10         else return a.idx>idx;
11     }
12 };
13 int f[100005];
14 int main(){
15     int n,q;
16     int i,j,k;
17     info now;
18     char ch;
19     while(scanf("%d",&n)!=EOF){
20         priority_queue<info>pq;
21         for(i=1;i<=n;++i){
22             scanf("%d",&f[i]);
23             now.idx=i;
24             now.key=f[i];
25             pq.push(now);
26         }
27         scanf("%d",&q);
28         while(q--){
29             getchar();
30             scanf("%c",&ch);
31             if(ch=='Q') {
32                 while(f[pq.top().idx]!=pq.top().key){
33                     pq.pop();
34                 }
35                 printf("%d %d\n",pq.top().idx,pq.top().key);
36             }
37             else{
38                 scanf("%d %d",&i,&j);
39                 f[i]=j;
40                 now.idx=i;
41                 now.key=j;
42                 pq.push(now);
43             }
44         }
45         puts("");
46     }
47     return 0;
48 }

 

posted @ 2013-04-27 19:36  _sunshine  阅读(184)  评论(0编辑  收藏  举报