poj 3468 A Simple Problem with Integers 降维线段树

这道题是区间更新线段树模板题

记录一下降维线段树

正常线段树是倍增的

rt<<1 rt<<1+1

这个线段树用了getid的方法使线段树降了一维

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<string>
  7 #include<ctime>
  8 #include<map>
  9 #include<set>
 10 #include<vector>
 11 #include<queue>
 12 #include<cstdlib>
 13 #include<cassert>
 14 #include<sstream>
 15 #include<stack>
 16 #include<list>
 17 #include<bitset>
 18 #define cl(a,b) memset(a,b,sizeof(a))
 19 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
 20 using namespace std;
 21 typedef long long ll;
 22 typedef long double ldb;
 23 typedef pair<int,int> pii;
 24
 25 #define ls getid(l,l+r>>1)
 26 #define rs getid((l+r>>1)+1,r)
 27 #define lson l,m,ls
 28 #define rson m+1,r,rs
 29
 30 typedef long long ll;
 31
 32 const int maxn = 1e5+10;
 33
 34 inline int getid(int x,int y)
 35 {
 36     return x+y|y!=x;
 37 }
 38
 39 ll rm[maxn<<1],col[maxn<<1];
 40
 41 void pushup(int l,int r,int rt)
 42 {
 43     rm[rt]=rm[ls]+rm[rs];
 44 }
 45
 46 void pushdown(int l,int r,int rt,int k)
 47 {
 48     if (col[rt])
 49     {
 50         col[ls] += col[rt];
 51         col[rs] += col[rt];
 52         rm[ls] += col[rt]*(k-(k>>1));
 53         rm[rs] += col[rt]*(k>>1);
 54         col[rt] = 0;
 55     }
 56 }
 57
 58 void build(int l,int r,int rt)
 59 {
 60     if(l == r)
 61     {
 62         scanf("%I64d",&rm[rt]);
 63         return ;
 64     }
 65     int m=l+r>>1;
 66     build(lson);
 67     build(rson);
 68     pushup(l,r,rt);
 69 }
 70
 71 void update(int L,int R,int c,int l,int r,int rt)
 72 {//区间更新
 73     if(L<=l && r<=R)
 74     {
 75         col[rt]+=c;
 76         rm[rt]+=c*(r-l+1);
 77         return ;
 78     }
 79     pushdown(l,r,rt,r-l+1);
 80     int m=l+r>>1;
 81     if( L <= m ) update(L,R,c,lson);
 82     if (R > m) update(L,R,c,rson);
 83     pushup(l,r,rt);
 84 }
 85
 86 void update(int p,int c,int l,int r,int rt)
 87 {//单点更新
 88     if(l==r)
 89     {
 90         rm[rt]+=c;
 91         return ;
 92     }
 93     int m=l+r>>1;
 94     if( p <= m ) update(p,c,lson);
 95     else update(p,c,rson);
 96     pushup(l,r,rt);
 97 }
 98
 99 ll query(int L,int R,int l,int r,int rt)
100 {
101     if( L<=l && r<=R )
102     {
103         return rm[rt];
104     }
105     pushdown(l,r,rt, r-l+1);
106     int m=l+r>>1;
107     ll ret = 0;
108     if( L<=m ) ret += query(L,R,lson);
109     if( m<R ) ret += query(L,R,rson);
110     return ret;
111 }
112
113 int main()
114 {
115     int n,m;
116     scanf("%d%d",&n,&m);
117     char str[2];
118     build(1,n,1);
119     while(m--)
120     {
121         int l,r,x;
122         scanf("%s",str);
123         if(str[0]==‘Q‘)
124         {
125             scanf("%d%d",&l,&r);
126             printf("%I64d\n",query(l,r,1,n,1));
127         }
128         else
129         {
130             scanf("%d %d %d", &l, &r, &x);
131             update(l, r, x, 1, n, 1);
132         }
133     }
134     return 0;
135 }/*
136
137 5 6
138 1 2 3 4 5
139 Q 1 5
140 U 3 6
141 Q 3 4
142 Q 4 5
143 U 2 9
144 Q 1 5
145
146 */
时间: 2024-10-23 01:53:15

poj 3468 A Simple Problem with Integers 降维线段树的相关文章

POJ 3468 A Simple Problem with Integers(线段树)

题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 56005   Accepted: 16903 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with

poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   Accepted: 17753 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)

题目链接 题意: 只有这两种操作 C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000."Q a b" means querying the sum of Aa, Aa+1, ... , Ab. 分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久. val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一. 1 #include <iostream

POJ 3468 A Simple Problem with Integers(线段树 区间更新)

Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. In

poj 3468 A Simple Problem with Integers 【线段树-成段更新】

题目:poj 3468 A Simple Problem with Integers 题意:给出n个数,两种操作 1:l -- r 上的所有值加一个值val 2:求l---r 区间上的和 分析:线段树成段更新,成段求和 树中的每个点设两个变量sum 和 num ,分别保存区间 l--r 的和 和l---r 每个值要加的值 对于更新操作:对于要更新到的区间上面的区间,直接进行操作 加上 (r - l +1)* val .下面的区间标记num += val 对于求和操作,每次进行延迟更新,把num值

poj 3468 A Simple Problem with Integers(线段树+区间更新+区间求和)

题目链接:id=3468http://">http://poj.org/problem? id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 83959   Accepted: 25989 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. Yo

POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)

题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 56005   Accepted: 16903 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with

poj 3468 A Simple Problem with Integers (线段树成段更新)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 77486   Accepted: 23862 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

Poj 3468 A Simple Problem with Integers(线段树 区间更新 延迟标记)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 73239   Accepted: 22607 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of