POJ 3468:A Simple Problem with Integers(线段树[成段更新])
题意:N个数Q次操作。一共两种操作:Q l r :询问[l,r]这个区间里的数字和,C l r c: [l,r]区间里的每个数都加上c。1 ≤ N,Q ≤ 100000.
方法:线段树的成段更新。注意懒惰标记。这只是为了有个模板。易错点在代码中以下划线标注。
- //16:06
- #include <cstdio>
- #include <cstring>
- #define N 100010
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- long long sum[N<<];
- long long col[N<<];//一直WA,只因这里写成Int。这个和上面那个要同个类型才是。
- void pushUp(int rt) {
- sum[rt] = sum[rt<<] + sum[rt<<|];
- }
- void pushDown(int len, int rt) {
- if (col[rt]) {
- col[rt<<] += col[rt];
- col[rt<<|] += col[rt];
- sum[rt<<] += (len-len/)*col[rt];
- sum[rt<<|] += (len/)*col[rt];
- col[rt] = ;
- }
- }
- void build(int l, int r, int rt) {
- col[rt] = ;
- if (l==r) {
- scanf("%lld", &sum[rt]);
- return;
- }
- int mid = (l+r)/;
- build(lson);
- build(rson);
- pushUp(rt);
- }
- void update(int L, int R, int v, int l, int r, int rt) {
- if (L <= l && r <= R) {
- col[rt] += v;
- sum[rt] += (r-l+1ll)*v;
- return;
- }
- pushDown(r-l+, rt);
- int mid = (l+r)/;
- if (L <= mid) update(L,R,v,lson);
- if (R > mid) update(L,R,v,rson);
- pushUp(rt);
- }
- long long query(int L, int R, int l, int r, int rt) {
- if (L <= l && r <= R) {
- return sum[rt];
- }
- pushDown(r-l+,rt);
- int mid = (l+r)/;
- long long ans = ;
- if (L <= mid) ans += query(L,R,lson);
- if (R > mid) ans += query(L,R,rson);
- return ans;
- }
- int main() {
- int n, q;
- while (scanf("%d%d", &n, &q) != EOF) {
- build(,n,);
- for (int i = ; i < q; i++) {
- char com[];
- scanf("%s", com);
- if (com[] == 'Q') {
- int l, r = ;
- scanf("%d%d", &l, &r);
- //printf("query %d %d\n", l, r);
- printf("%lld\n", query(l,r,,n,));
- } else if (com[] == 'C') {
- int l, r, add;
- scanf("%d%d%d", &l, &r, &add);
- update(l,r,add,,n,);
- }
- }
- }
- return ;
- }
另外感觉三个函数有很多重复点,写了一个紧凑版本,不过看起来代码量差不多,而且效率低了呢。
- //16:06
- #include <cstdio>
- #include <cstring>
- #define N 100010
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- long long sum[N<<];
- long long col[N<<];
- void pushUp(int rt) {
- sum[rt] = sum[rt<<] + sum[rt<<|];
- }
- void pushDown(int len, int rt) {
- if (col[rt]) {
- col[rt<<] += col[rt];
- col[rt<<|] += col[rt];
- sum[rt<<] += (len-len/)*col[rt];
- sum[rt<<|] += (len/)*col[rt];
- col[rt] = ;
- }
- }
- long long basicDo(bool isBuild, int L, int R, int v, int l, int r, int rt) {
- if (isBuild) col[rt] = ;
- if (l == r || L <= l && r <= R) {
- if (isBuild) scanf("%lld", &sum[rt]);
- col[rt] += v;
- sum[rt] += (r-l+1ll)*v;
- return sum[rt];
- }
- pushDown(r-l+, rt);
- int mid = (l+r)/;
- long long ans = ;
- if (isBuild || L<= mid) ans += basicDo(isBuild,L,R,v,lson);
- if (isBuild || R > mid) ans += basicDo(isBuild,L,R,v,rson);
- pushUp(rt);
- return ans;
- }
- void build(int l, int r, int rt) {
- basicDo(true, ,,,l,r, rt);
- }
- void update(int L, int R, int v, int l, int r, int rt) {
- basicDo(false, L, R, v, l, r, rt);
- }
- long long query(int L, int R, int l, int r ,int rt) {
- return basicDo(false, L, R, , l, r, rt);
- }
- int main() {
- int n, q;
- while (scanf("%d%d", &n, &q) != EOF) {
- build(,n,);
- for (int i = ; i < q; i++) {
- char com[];
- scanf("%s", com);
- if (com[] == 'Q') {
- int l, r = ;
- scanf("%d%d", &l, &r);
- //printf("query %d %d\n", l, r);
- printf("%lld\n", query(l,r,,n,));
- } else if (com[] == 'C') {
- int l, r, add;
- scanf("%d%d%d", &l, &r, &add);
- update(l,r,add,,n,);
- }
- }
- }
- return ;
- }
POJ 3468:A Simple Problem with Integers(线段树[成段更新])的更多相关文章
- POJ 3468 A Simple Problem with Integers (线段树成段更新)
题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...
- [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ...
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 75541 ...
- POJ 3468 A Simple Problem with Integers //线段树的成段更新
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 59046 ...
随机推荐
- nginx日志相关优化安全
一.编写脚本实现nginx access日志轮询 配置日志切割脚本,如下: [root@nginx shell]# cat cut_nginx_log.sh #!/bin/bash #Author:M ...
- settings.py常规配置项
settings.py常见配置项 1. 配置Django_Admin依照中文界面显示 LANGUAGE_CODE = 'zh-hans' 2. 数据库配置(默认使用sqlite3) 使用MySQL的配 ...
- python基本操作(五)
if 判断 if 条件: 代码1 代码2 代码3 代码块(同一缩进级别的代码,例如代码1.代码2和代码3是相同缩进的代码,这三个代码组合在一起就是一个代码块,相同缩进的代码会自上而下的运行) cls ...
- java做http接口
问题描述 我要对外提供一个http接口给别人调用...但是我不知道用java怎么做这个接口.请大家详细给我讲讲.从开发到如何发布到服务器.谢谢了 解决方案 如果你这个很简单的话,而且数量也很少,建议直 ...
- manjaro18 配置国内镜像源
1.配置镜像源: sudo pacman-mirrors -i -c China -m rank 2.设置 archlinuxcn 源: sudo nano /etc/pacman.conf 添加以下 ...
- stm32L0工程建立(HAL+IAR,无cubemx)
https://files.cnblogs.com/files/CodeWorkerLiMing/STM32HAL%E5%BA%93%E5%AD%A6%E4%B9%A0%E2%80%94%E5%B7% ...
- POJ:3160-Father Christmas flymouse
Father Christmas flymouse Time Limit: 1000MS Memory Limit: 131072K Description After retirement as c ...
- German Collegiate Programming Contest 2018
// Coolest Ski Route #include <iostream> #include <cstdio> #include <cstring> #inc ...
- 奇数结点升序偶数结点降序的单链表排序(Python实现)
题目 一个链表,奇数结点升序,偶数结点降序,要求变成一个全升序的链表. 例如:1->8->2->7->3->6->4->5,变为1->2->3-& ...
- BZOJ 5390: [Lydsy1806月赛]糖果商店
F[i][j]表示总重量为i,最上面那个盒子中糖果种类为j的方案数 每次新加一个盒子,或者在原来盒子中加入一个糖 F[i][0]为中间状态,优化转移(表示最上面那个盒子不能加糖果) #include& ...