码迷,mamicode.com
首页 > 其他好文 > 详细

2014 summer 知识点总结1之线段树

时间:2014-07-30 11:56:23      阅读:450      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   strong   io   for   

HDU 1166

【题意】:

n个阵营一字排开,每个初始有a[i]个人。现有两种操作:

Q a b 查询[a,b]之间总人数并输出

A/S a b 在a号位添加/删除b个人

【分析】:最基本的单点更新和区间查询,维护节点信息sum[o]

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 
 5 using namespace std;
 6 
 7 int numv[50005<<2];
 8 int A[50005];
 9 
10 void builtTree(int o,int l,int r){
11     if(l==r) {
12         numv[o]=A[l];
13         return ;
14     }
15     int m=l+(r-l)/2;
16     builtTree(2*o,l,m);
17     builtTree(2*o+1,m+1,r);
18     numv[o]=numv[2*o]+numv[2*o+1];
19     return ;
20 }
21 void Update(int o,int l,int r,int p,int x){
22     if(l==r && l==p){
23         A[l]=x;
24         numv[o]=x;
25         return ;
26     }
27     int m=l+(r-l)/2;
28     if (p<=m) Update(2*o,l,m,p,x);
29     if (p>=m+1)Update(2*o+1,m+1,r,p,x);
30     numv[o]=numv[2*o]+numv[2*o+1];
31 }
32 int Query(int ql,int qr,int o,int l,int r){
33     if (ql<=l && r<=qr) return numv[o];
34     int m=l+(r-l)/2;
35     int ans=0;
36     if (ql<=m) ans+=Query(ql,qr,2*o,l,m);
37     if (m+1<=qr) ans+=Query(ql,qr,2*o+1,m+1,r);
38     return ans;
39 }
40 int t,n;
41 int main(){
42     scanf("%d",&t);
43     for(int cas=1;cas<=t;cas++){
44         scanf("%d",&n);
45         printf("Case %d:\n",cas);
46         for(int i=1;i<=n;i++) scanf("%d",&A[i]);
47         builtTree(1,1,n);
48         char s[105];
49         while(~scanf("%s",s)){
50             if (s[0]==E) {
51                 break;
52             }
53             int a,b;
54             scanf("%d%d",&a,&b);
55             if (s[0]==Q){
56                 int ans=Query(a,b,1,1,n);
57                 printf("%d\n",ans);
58             }
59             if (s[0]==A){
60                 Update(1,1,n,a,A[a]+b);
61             }
62             if (s[0]==S){
63                 Update(1,1,n,a,A[a]-b);
64             }
65         }
66     }
67     return 0;
68 }
View Code

 

HDU 1754

【题意】:给n个数字。m次操作,每次操作更新一个数字或者查询区间最大值。

【分析】:基本单点更新区间查询,维护节点信息max[o]

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #define Mod 1000000007
 5 #define LL long long
 6 #define toL 2*o,l,m
 7 #define toR 2*o+1,m+1,r
 8 using namespace std;
 9 
10 int maxv[200005<<2];
11 int A[200005];
12 
13 void builtTree(int o,int l,int r){
14     if (l==r){
15         maxv[o]=A[l];
16         return ;
17     }
18     int m=(l+r)/2;
19     builtTree(toL);
20     builtTree(toR);
21     maxv[o]=max(maxv[2*o],maxv[2*o+1]);
22     return ;
23 }
24 void Updata(int o,int l,int r,int p,int x){
25     if (l==r && p==l){
26         maxv[o]=x;
27         return ;
28     }else {
29         int m=(r+l)/2;
30         if (p<=m) Updata(toL,p,x);
31         if (m+1<=p) Updata(toR,p,x);
32         maxv[o]=max(maxv[2*o],maxv[2*o+1]);
33         return ;
34     }
35 }
36 int Query(int o,int l,int r,int ql,int qr){
37     if (ql<=l && r<=qr) return maxv[o];
38     int m=(r+l)/2;
39     int ans=-1;
40     if (ql<=m) ans=max(ans,Query(toL,ql,qr));
41     if (m+1<=qr) ans=max(ans,Query(toR,ql,qr));
42     return ans;
43 }
44 int n,q;
45 
46 int main(){
47     while(~scanf("%d%d",&n,&q)){
48         for(int i=1;i<=n;i++) scanf("%d",&A[i]);
49         builtTree(1,1,n);
50         for(int i=1;i<=q;i++){
51             int a,b;
52             char s[3];
53             scanf("%s%d%d",s,&a,&b);
54             if (s[0]==Q){
55                 printf("%d\n",Query(1,1,n,a,b));
56             }
57             if (s[0]==U){
58                 Updata(1,1,n,a,b);
59             }
60         }
61     }
62     return 0;
63 }
View Code

 

HDU 1394

【题意】:就是给出一串数,当依次在将第一个数变为最后一个数的过程中,要你求它的最小逆序数。

【分析】:每次维护sumv求区间内有多少个数字,处理出LOW[],UP[]后利用sum每次枚举

       for(int i=1;i<=n;i++){
            scanf("%d",&A[i]);
            A[i]++;
        //    cout<<"Q="<<Query(1,1,n,A[i]+1,n)<<endl;
            if (A[i]+1<=n) sum+=Query(1,1,n,A[i]+1,n);
            updata(1,1,n,A[i],1);//令A【i】的位置为1,那么sunv就相当于一个求和了
            A[i]--;//信息已经保存到树中,A[i]可还原
        }

【代码】:

bubuko.com,布布扣
 1 /*HDU1394搜索写法*/
 2 #include <iostream>
 3 #include <string.h>
 4 #include <stdio.h>
 5 #define LL 2*o,l,m
 6 #define LR 2*o+1,m+1,r
 7 using namespace std;
 8 
 9 int A[50005];
10 int Low[50005],Up[50005];
11 int numv[50005<<2];//[1...50005]有多少个数
12 
13 int Query(int o,int l,int r,int ql,int qr){
14     if (ql<=l && r<=qr) return numv[o];
15     int m=(r+l)>>1;
16     int ans=0;
17     if (ql<=m) ans+=Query(LL,ql,qr);
18     if (m+1<=qr) ans+=Query(LR,ql,qr);
19     return ans;
20 }
21 void updata(int o,int l,int r,int p,int x){
22    // cout<<"l="<<l<<","<<"r="<<r<<endl;
23 
24     if (l==r && p==l) {
25         numv[o]=1;
26         return ;
27     }
28     int m=(r+l)>>1;
29     if (p<=m)updata(LL,p,x);
30     if (m+1<=p)updata(LR,p,x);
31     numv[o]=numv[2*o]+numv[2*o+1];
32     return;
33 }
34 int main(){
35     int n;
36     while(~scanf("%d",&n)){
37         memset(numv,0,sizeof(numv));
38         int ans,sum=0;
39         for(int i=1;i<=n;i++){
40             scanf("%d",&A[i]);
41             A[i]++;
42         //    cout<<"Q="<<Query(1,1,n,A[i]+1,n)<<endl;
43             if (A[i]+1<=n) sum+=Query(1,1,n,A[i]+1,n);
44             updata(1,1,n,A[i],1);//令A【i】的位置为1,那么sunv就相当于一个求和了
45             A[i]--;//信息已经保存到树中,A[i]可还原
46         }
47         ans=sum;
48         for(int i=0;i<n;i++){
49             Low[i]=i;
50             Up[i]=n-i-1;
51         }
52         for(int i=1;i<=n-1;i++){
53             sum=sum+(Up[A[i]]-Low[A[i]]);
54             ans=min(sum,ans);
55         }
56         printf("%d\n",ans);
57     }
58     return 0;
59 }
View Code

 

 

【题意】:

【分析】:

【代码】:

 

 

 

【题意】:

【分析】:

【代码】:

2014 summer 知识点总结1之线段树,布布扣,bubuko.com

2014 summer 知识点总结1之线段树

标签:style   blog   http   color   os   strong   io   for   

原文地址:http://www.cnblogs.com/little-w/p/3877313.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!