当前位置: 首页 > news >正文

A Simple Problem with Integers(线段树)

目录

描述

输入

输出

样例输入 

样例输出 

思路

建树 

第一次错误解法(正确解法在下面,可跳过这一步)

正确解法

code 


描述

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.

输入

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

输出

You need to answer all Q commands in order. One answer in a line.

样例输入 

10 5
C 3 6 3
Q 2 4

样例输出 

9
15

思路

不要看这题全英文,但这题就是属于线段树模版题,基本做法是一样的

建树 

第一次错误解法(正确解法在下面,可跳过这一步)

树没有更新成功,id=10,id=11理论上是要继续更新他们的sum值,但我的错误代码没有更新

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
const int N = 100010;
#define ll long long
ll nums[N];
struct Tree {int l, r;ll sum;ll tag;
}tree[N << 2];
void pushup(int u) {tree[u].sum = tree[u << 1].sum + tree[u << 1 | 1].sum;
}
void build(int l, int r, int u) {if (l == r) tree[u] = { l,r,nums[l] };//要与结构体Tree一一对应 else {tree[u] = { l,r };int mid = (l + r) >> 1;build(l, mid, u << 1);build(mid + 1, r, u << 1 | 1);pushup(u);}
}
ll query(int L, int R, int u) {int l = tree[u].l, r = tree[u].r;if (l >= L && r <= R)return tree[u].sum;int mid = (l + r) >> 1;ll sum = 0;if (L <= mid) sum += query(L, R, u << 1);if (R > mid) sum += query(L, R, u << 1 | 1);return sum;
}
void pushdown(int u, int ln, int rn) {if (tree[u].tag) {tree[u << 1].tag += tree[u].tag;tree[u << 1 | 1].tag += tree[u].tag;tree[u << 1].sum += tree[u].tag * ln;tree[u << 1 | 1].sum += tree[u].tag * rn;tree[u].tag = 0;}
}
void updatespan(int L, int R, int value, int u) {int l = tree[u].l, r = tree[u].r;int mid = (l + r) >> 1;if (l >= L && r <= R) {tree[u].tag += value;tree[u].sum += value * (r - l + 1);return;}pushdown(u, mid - l + 1, r - mid);if (L <= mid) updatespan(L, R, value, u << 1);if (R > mid) updatespan(L, R, value, u << 1 | 1);pushup(u);
}
int main()
{int n, q;while (scanf("%d%d", &n, &q) != EOF) {for (int i = 1; i <= n; i++) scanf("%lld", &nums[i]);build(1, n, 1);while (q--) {string cz;int op1, op2;cin >> cz;if (cz == "C") {int val;scanf("%d%d%d", &op1, &op2, &val);updatespan(op1, op2, val, 1);}else {scanf("%d%d", &op1, &op2);printf("%lld\n", query(op1, op2, 1));}}}return 0;
}

正确解法

关键在于updatespan函数中,if语句中我没有继续pushdown导致错误

  

code 

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
const int N = 100010;
#define ll long long
ll nums[N];
struct Tree {int l, r;ll sum;ll tag;
}tree[N << 2];
void pushup(int u) {tree[u].sum = tree[u << 1].sum + tree[u << 1 | 1].sum;
}
void build(int l, int r, int u) {if (l == r) {tree[u] = { l,r,nums[l] };//要与结构体Tree一一对应 else {tree[u] = { l,r };int mid = (l + r) >> 1;build(l, mid, u << 1);build(mid + 1, r, u << 1 | 1);pushup(u);}
}
ll query(int L, int R, int u) {int l = tree[u].l, r = tree[u].r;if (l >= L && r <= R)return tree[u].sum;int mid = (l + r) >> 1;ll sum = 0;if (L <= mid) sum += query(L, R, u << 1);if (R > mid) sum += query(L, R, u << 1 | 1);return sum;
}
void pushdown(int u, int ln, int rn) {if (tree[u].tag) {tree[u << 1].tag += tree[u].tag;tree[u << 1 | 1].tag += tree[u].tag;tree[u << 1].sum += tree[u].tag * ln;tree[u << 1 | 1].sum += tree[u].tag * rn;tree[u].tag = 0;}
}
void updatespan(int L, int R, int value, int u) {int l = tree[u].l, r = tree[u].r;int mid = (l + r) >> 1;if (l >= L && r <= R) {tree[u].tag += value;tree[u].sum += value * (r - l + 1);pushdown(u, mid - l + 1, r - mid);//关键return;}pushdown(u, mid - l + 1, r - mid);if (L <= mid) updatespan(L, R, value, u << 1);if (R > mid) updatespan(L, R, value, u << 1 | 1);pushup(u);
}
int main()
{int n, q;while (scanf("%d%d", &n, &q) != EOF) {for (int i = 1; i <= n; i++) scanf("%lld", &nums[i]);build(1, n, 1);while (q--) {string cz;int op1, op2;cin >> cz;if (cz == "C") {int val;scanf("%d%d%d", &op1, &op2, &val);updatespan(op1, op2, val, 1);}else {scanf("%d%d", &op1, &op2);printf("%lld\n", query(op1, op2, 1));}}}return 0;
}

http://www.lryc.cn/news/328374.html

相关文章:

  • 单元测试(UT)用例简介
  • Java通过反射机制获取类对象下的属性值
  • IDEA插件开发-File -> New->Project中添加一个myOptions
  • 海量数据处理项目-账号微服务和流量包数据库表+索引规范(下)
  • Nodejs 16与 gitbook搭建属于你自己的书本网站-第一篇
  • 服务器被CC攻击之后怎么办?
  • pygame通过重心坐标 用纹理填充三角形
  • Leetcode 611. 有效三角形的个数
  • Openfeign
  • 五、基于KubeAdm搭建多节点K8S集群
  • PC电脑技巧[笔记本通过网线访问设备CMW500]
  • 【接口自动化测试框架】YAML管理接口框架配置的最佳实践
  • 【进程OI】基本文件操作的系统调用
  • Ubuntu20.04 server系统部署安装(VMware上)和初始化配置
  • 图论最短路径以及floyd算法的MATLAB实现
  • 微信小程序 - 登录功能实现
  • Python连接MySQL
  • 水泊梁山108小酒坛之呼保义宋江
  • java.lang.ClassNotFoundException: javafx.application.Application
  • 腾讯 tendis 替代 redis linux安装使用
  • k8s调优--来自gpt
  • HTML5+CSS3小实例:旋转中的视差效果
  • 3-zookeeper之ZAB协议
  • 如何为企业策划一场XR虚拟直播?
  • 6.3物联网RK3399项目开发实录-驱动开发之I2C 使用(wulianjishu666)
  • HarmonyOS实战开发-如何构建多种样式弹窗
  • 《Effective C++》《构造/析构/赋值运算——7、为多态基类声明virtual析构函数》
  • Type-C一分二快充线智能分配方案
  • 利用python脚本,根据词条爬取百度图片(爬虫)
  • java复原IP 地址(力扣Leetcode93)