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

HDU 1166

【题意】:

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

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

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

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

【代码】:

 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 }

HDU 1754

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

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

【代码】:

 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 }

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]可还原
        }

【代码】:

 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 }

【题意】:

【分析】:

【代码】:

【题意】:

【分析】:

【代码】:

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

时间: 2024-10-09 09:36:19

2014 summer 知识点总结1之线段树的相关文章

线段树分治

2014徐寅展论文<线段树在一类分治问题上的应用>读后感. 线段树分治 线段树分治其实就是有撤销操作的时间分治. 题目让你维护一些信息,每次可以询问,可以执行一种操作,也可以将之前的某个这种操作撤回. 操作容易维护,但撤回操作不容易维护. 需要将操作,询问都离线下来.将时间轴画出来,那么每个操作只在时间轴上的一个区间内生效. 用线段树给这个区间打上这个操作的标记,维护信息. TJOI2018 数学计算 小豆现在有一个数x,初始值为1. 小豆有Q次操作,操作有两种类型: m: x = x * m

2014 Super Training #7 E Calculate the Function --矩阵+线段树

原题:ZOJ 3772 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3772 这题算是长见识了,还从没坐过矩阵+线段树的题目呢,不要以为矩阵就一定配合快速幂来解递推式的哦. 由F(x)=F(x-1)+F(x-2)*A[x],转化为矩阵乘法:  ===> 所以维护一颗线段树,线段树的每个结点保存一个矩阵,叶子节点为: a[0][0] = a[1][0] = 1, a[0][1] = Ax, a[1][1] = 0的形式

hdu-4893-Wow! Such Sequence!-线段树【2014多校第三场-J】

题意:一个初始为0的数组,支持三种操作:1.向第k个数添加d,(|d| < 2^31);2.把[l, r]区间内的数字都换成与它最相近的Fibonacci数;3.询问[l, r]区间的和. 思路:初始化Fibonacci数组,longlong 类型内90个就够用了. 线段树区间查询,用lazy标记, sgt[]记录线段树各个节点的区间和, fib_num_sum[]记录与各个叶子节点当前值最接近的Fibonacci数,传递到区间fib_num_sum[]就是区间Fibonacci数的和. 操作1

HDU_4893 2014多校三 线段树

给定一个初始都为0的序列,有三种操作,前两种比较正常,一个是对某个位置的数add k,另一个是query区间和.然后比较麻烦的是第三个操作,把某个区间里面的每个值改成离它最近的Fibonacci数,如果存在左右两个离它近的,优先取左边数值小的 一看到前两个操作马上就想上手敲树状数组,后来看到第三个就有点傻眼了,思维当时一直停留在怎么快速改值..但忽略了题目本身要求什么,只有操作2才是输出,也就是只要求区间和值而且,其他两个都是操作而已,在聪哥的提醒下,知道对线段树开两个值记录+一个懒惰标记,一个

2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个mark坑了我好几个小时..哎.太弱. 先DFS这棵树,树形结构转换为线性结构,每个节点有一个第一次遍历的时间和最后一次遍历的时间,之间的时间戳都为子树的时间戳,用线段树更新这段区间即可实现更新子树的效果,用到懒操作节省时间. 坑我的地方: update时,不能写成:tree[rt].mark = 1,

URAL 2014 Zhenya moves from parents 线段树

线段树,前缀和最小 Zhenya moves from parents Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Zhenya moved from his parents' home to study in other city. He didn't take any cash with him, he only took his f

2014多校3 Wow! Such Sequence!线段树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 这题实在是让人纠结啊--好久不写线段树的题了,因为这几天学伸展树,然后觉得线段树小case了.没想到栽在这题上了.尼玛-- 自己把自己给搞晕了--想复杂了,都不懂得预处理一下,唉--还得怒刷几十道啊!! #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #in

2014多校1011--hdu--4097--Killing Monsters(塔防,线段树超时。。)

Killing Monsters Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 107    Accepted Submission(s): 54 Problem Description Kingdom Rush is a popular TD game, in which you should build some towers

[hdu 5032]2014北京网络赛Always Cook Mushroom 离散化+离线线段树/树状数组

Always Cook Mushroom Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 196    Accepted Submission(s): 54 Problem Description Matt has a company, Always Cook Mushroom (ACM), which produces high-q