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

题目传送门

  1 /*
  2     线段树-成段更新:裸题,成段增减,区间求和
  3     注意:开long long:)
  4 */
  5 #include <cstdio>
  6 #include <iostream>
  7 #include <algorithm>
  8 #include <cstring>
  9 #include <cmath>
 10 using namespace std;
 11
 12 #define lson l, mid, rt << 1
 13 #define rson mid + 1, r, rt << 1 | 1
 14 #define LL long long
 15
 16 const int MAXN = 1e5 + 10;
 17 const int INF = 0x3f3f3f3f;
 18 struct Node
 19 {
 20     LL sum, add;
 21 }node[MAXN << 2];
 22
 23 void push_up(int rt)
 24 {
 25     node[rt].sum = node[rt<<1].sum + node[rt<<1|1].sum;
 26 }
 27
 28 void push_down(int rt, int c)
 29 {
 30     if (node[rt].add)
 31     {
 32         node[rt<<1].add += node[rt].add;
 33         node[rt<<1|1].add += node[rt].add;
 34         node[rt<<1].sum += node[rt].add * (c - (c >> 1));
 35         node[rt<<1|1].sum += node[rt].add * (c >> 1);
 36         node[rt].add = 0;
 37     }
 38 }
 39
 40 void build(int l, int r, int rt)
 41 {
 42     node[rt].add = 0;
 43     if (l == r)    {scanf ("%I64d", &node[rt].sum);    return ;}
 44     int mid = (l + r) >> 1;
 45     build (lson);    build (rson);
 46
 47     push_up (rt);
 48 }
 49
 50 void updata(int ql, int qr, int c, int l, int r, int rt)
 51 {
 52     if (ql <= l && r <= qr)    {node[rt].sum += (LL) c * (r - l + 1);    node[rt].add += c;    return ;}
 53
 54     push_down (rt, r - l + 1);
 55
 56     int mid = (l + r) >> 1;
 57     if (ql <= mid)    updata (ql, qr, c, lson);
 58     if (qr > mid)    updata (ql, qr, c, rson);
 59
 60     push_up (rt);
 61 }
 62
 63 LL query(int ql, int qr, int l, int r, int rt)
 64 {
 65     if (ql <= l && r <= qr)    return node[rt].sum;
 66
 67     push_down (rt, r - l + 1);
 68
 69     int mid = (l + r) >> 1;        LL ans = 0;
 70     if (ql <= mid)    ans += query (ql, qr, lson);
 71     if (qr > mid)    ans += query (ql, qr, rson);
 72
 73     return ans;
 74 }
 75
 76 int main(void)        //POJ 3468 A Simple Problem with Integers
 77 {
 78     //freopen ("POJ_3468.in", "r", stdin);
 79
 80     int n, q;
 81     while (scanf ("%d%d", &n, &q) == 2)
 82     {
 83         build (1, n, 1);
 84         while (q--)
 85         {
 86             char s[3];    int ql, qr, c;
 87             scanf ("%s", &s);
 88             if (s[0] == ‘Q‘)
 89             {
 90                 scanf ("%d%d", &ql, &qr);
 91                 printf ("%I64d\n", query (ql, qr, 1, n, 1));
 92             }
 93             else
 94             {
 95                 scanf ("%d%d%d", &ql, &qr, &c);
 96                 updata (ql, qr, c, 1, n, 1);
 97             }
 98         }
 99     }
100
101     return 0;
102 }
时间: 2024-12-05 21:08:02

线段树(成段更新) POJ 3468 A Simple Problem with Integers的相关文章

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 【线段树-成段更新】

题目: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 ——线段树 成段更新 懒惰标记

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 given number to each

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 线段树成段更新

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

POJ 2777 Count Color (线段树成段更新+二进制思维)

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

POJ 2528 Mayor&#39;s posters 线段树成段更新+离散化

题目来源:POJ 2528 Mayor's posters 题意:很多张海报贴在墙上 求可以看到几张海报 看那两张图就行了 第一张俯视图 思路:最多2W个不同的数 离散化一下 然后成段更新 a[rt] = i代表这个区间是第i张报纸 更新玩之后一次query cover[i]=1代表可以看到第i张报纸 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const