poj3468A Simple Problem with Integers

题目链接:http://poj.org/problem?id=3468

区间更新,区间求和。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 #define ll long long
 5 #define lson l,m,rt<<1
 6 #define rson m+1,r,rt<<1|1
 7 const int maxn=100010;
 8 ll add[maxn<<2];
 9 ll sum[maxn<<2];
10
11
12 void pushup(int rt)
13 {
14     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
15 }
16 void pushdown(int rt,int m)
17 {
18     if(add[rt])
19     {
20         add[rt<<1]+=add[rt];
21         add[rt<<1|1]+=add[rt];
22         sum[rt<<1]+=add[rt]*(m-(m>>1));
23         sum[rt<<1|1]+=add[rt]*(m>>1);
24         add[rt]=0;
25     }
26 }
27
28 void build(int l,int r,int rt)
29 {
30             add[rt]=0;
31     if(l==r) {
32         scanf("%lld",&sum[rt]);
33         return;
34     }
35     int m=(l+r)>>1;
36     build(lson);
37     build(rson);
38     pushup(rt);
39 }
40
41 void update(int L,int R,int c,int l,int r,int rt)
42 {
43     if(L<=l&&r<=R){
44              add[rt]+=c;
45         sum[rt]+=(ll)c*(r-l+1);
46         return ;
47     }
48     pushdown(rt,r-l+1);
49     int m=(l+r)>>1;
50     if(L<=m) update(L,R,c,lson);
51     if(R>m) update(L,R,c,rson);
52     pushup(rt);
53 }
54
55 ll query(int L,int R,int l,int r,int rt)
56 {
57     if(L<=l&&r<=R)
58     {
59         return sum[rt];
60     }
61     pushdown(rt,r-l+1);
62     ll ans=0;
63     int m=(l+r)>>1;
64     if(L<=m) ans+=query(L,R,lson);
65     if(R>m) ans+=query(L,R,rson);
66     return ans;
67 }
68
69 int main()
70 {
71     int n,m;
72     while(scanf("%d%d",&n,&m)!=EOF)
73     {
74
75         build(1,n,1);
76         while(m--)
77         {
78             int a,b,c;
79             char s[2];
80             scanf("%s",s);
81             if(s[0]==‘Q‘)
82             {
83                 scanf("%d%d",&a,&b);
84                 printf("%lld\n",query(a,b,1,n,1));
85             }
86             else {
87                 scanf("%d%d%d",&a,&b,&c);
88                 update(a,b,c,1,n,1);
89             }
90
91         }
92     }
93     return 0;
94 }
时间: 2024-10-19 05:22:01

poj3468A Simple Problem with Integers的相关文章

poj3468A Simple Problem with Integers(线段树的区域更新)

http://poj.org/problem?id=3468 真心觉得这题坑死我了,一直错,怎么改也没戏,最后tjj把q[rt].lz改成了long long 就对了,真心坑啊. 线段树的区域更新. 线段树功能:update:成段增减 query:区间求和 #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; #d

poj3468A Simple Problem with Integers区间和线段树

同上... #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include

poj3468A Simple Problem with Integers(线段树+成段更新)

题目链接: huangjing题意: 给n个数,然后有两种操作. [1]Q a b 询问a到b区间的和. [2]C a b c将区间a到b的值都增加c. 思路: 线段树成段更新的入门题目..学会使用lazy即可.还需要注意的是,lazy的时候更改是累加,而不是直接修改..有可能连续几次进行修改操作..注意这一点就好了... 题目: Language: Default A Simple Problem with Integers Time Limit: 5000MS   Memory Limit:

POJ-3468A Simple Problem with Integers,线段数区间更新查询,代码打了无数次还是会出错~~

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K                Case Time Limit: 2000MS 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 gi

【成端更新线段树模板】POJ3468-A Simple Problem with Integers

http://poj.org/problem?id=3468 _(:зゝ∠)_我又活着回来啦,前段时间太忙了写的题没时间扔上来,以后再说. [问题描述] 成段加某一个值,然后询问区间和. [思路] 讲一下pushdown和pushup出现的几个位置. pushup: (1)build的结尾,当叶子节点分别有对应的值后,它的父亲们就等于它们求和. (2)update的结尾,因为此时当前根的左右孩子已经更新了,故它也需要更新. pushdown(延迟标记): *pushdown会出现在一切要从当前结

POJ3468-A Simple Problem with Integers(区间更新 + SegmentTree || SplayTree || BinaryIndexTree)

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

poj3468A Simple Problem with Integers 线段树

//两个操作,第一个区间[a , b]内的所有数加c //第二个询问区间[a , b]的值 //很标准的线段数 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 1e5+10 ; #define left v<<1 #define right v<<1|1 typedef __int64 ll ; ll h[ma

POJ3468--A Simple Problem with Integers(Splay Tree)

虽然有点难,但是这套题都挂了一个月了啊喂…… 网上模板好多……最后还是抄了kuangbin聚聚的,毕竟好多模板都是抄他的,比较习惯…… POJ 3468 题意:给n个数,两种操作,区间整体加一个数,或者区间求和. 题解:把区间的前一个数挪到根,区间后一个数挪到根的右子树,根的右子树的左子树就是要处理的区间... SplayTree是一个二叉排序树,它所保存的顺序是数字的编号,所以无论怎样旋转,编号的顺序都不会变... 在首尾各插入一个结点,这样求整个区间的时候也可以找到前一个数和后一个数...

E - A Simple Problem with Integers

#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; #define N 100002 struct node { int l,r; long long lz,w; }q[4*N]; void pushup(int rt) { q[rt].w=q[rt*2].w+q[rt*2+1].w; } void pushdo