GXU - 7D - 区间求和 - 前缀和
https://oj.gxu.edu.cn/contest/7/problem/D
描述
有一个所有元素皆为0的数组A,有两种操作:
1 l r x表示将A区间[l,r]内所有数加上x;
2 l r表示将A区间[l,r]内从左往右数第i个数加上i;
给出m个操作,请输出操作结束后A中的最大值。
输入
第一行一个整数m,表示操作的个数
接下来有m行,表示操作的内容,具体格式与题目中一致
0<=m<=10^6
1<=l<=r<=10^6
0<=x<=10^9
输出
输出一个整数,表示所有操作之后A中的最大值
思路,差分,难点在于三角形怎么处理。
其实也不难,计算一下有几个三角形在哪里出现又消失就可以了。当三角形消失的时候解除掉三角形对当前的影响就足够了。
首先对差分求前缀和可以复原原数组,这个简单。
那么对三角形数量差分求前缀和可以复原每个区间的三角形的数量。
发现每一个三角形会使得前缀和增加1,解除这个三角形的时候就要把它的贡献一并解除掉。显然贡献就是区间长。
所以这个数据结构可以叫做“LD三角形区间修改前缀和”?
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll x = 0;
bool f = 0;
char c;
do {
c = getchar();
if(c == '-')
f = 1;
} while(c < '0' || c > '9');
do {
x = (x << 3) + (x << 1) + c - '0';
c = getchar();
} while(c >= '0' && c <= '9');
return f ? -x : x;
}
inline void _write(ll x) {
if(x > 9)
_write(x / 10);
putchar(x % 10 + '0');
}
inline void write(ll x) {
if(x < 0) {
putchar('-');
x = -x;
}
_write(x);
putchar('\n');
}
/*--- ---*/
const int MAXM = 1000000;
ll df1[MAXM+5];
int df2[MAXM+5];
inline void update(int l, int r, ll v) {
df1[l]+=v;
df1[r+1]-=v;
}
inline void update2(int l, int r) {
df2[l]+=1;
df2[r+1]-=1;
df1[r+1]-=(r-l+1);
}
inline ll calc() {
ll ans=0;
int curd=0;
ll curs=0;
for(int i=1;i<=MAXM;i++){
curd+=df2[i];
curs+=curd;
curs+=df1[i];
if(curs>ans)
ans=curs;
}
return ans;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out","w",stdout);
#endif // Yinku
int m=read();
while(m--){
int op=read(),l=read(),r=read();
if(op==1){
int x=read();
update(l,r,x);
}
else{
update2(l,r);
}
}
write(calc());
}
要是少一个数量级其实可以线段树:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll x = 0;
//int f = 0;
char c;
do {
c = getchar();
/*if(c == '-')
f = 1;*/
} while(c < '0' || c > '9');
do {
x = (x << 3) + (x << 1) + c - '0';
c = getchar();
} while(c >= '0' && c <= '9');
//return f ? -x : x;
return x;
}
inline void _write(int x) {
if(x > 9)
_write(x / 10);
putchar(x % 10 + '0');
}
inline void write(int x) {
if(x < 0) {
putchar('-');
x = -x;
}
_write(x);
putchar('\n');
}
/*--- ---*/
const int MAXM = 1000000;
ll a[MAXM + 5];
ll lazy[(MAXM << 2) + 5];
int lazy2[(MAXM << 2) + 5];
inline void push_down(int o, int l, int r) {
if(lazy[o] || lazy2[o]) {
lazy[o << 1] += lazy[o];
lazy[o << 1 | 1] += lazy[o];
int m = (l + r) >> 1;
lazy2[o << 1] += lazy2[o];
lazy2[o << 1 | 1] += lazy2[o];
lazy[o << 1 | 1] += (m - l + 1) * lazy2[o];
lazy[o] = 0;
lazy2[o] = 0;
}
}
void build() {
memset(a, 0, sizeof(a));
memset(lazy, 0, sizeof(lazy));
memset(lazy2, 0, sizeof(lazy2));
}
void update(int o, int l, int r, int a, int b, ll v) {
if(a <= l && r <= b) {
lazy[o] += v;
return;
} else {
push_down(o, l, r);
int m = (l + r) >> 1;
if(a <= m)
update(o << 1, l, m, a, b, v);
if(b >= m + 1)
update(o << 1 | 1, m + 1, r, a, b, v);
}
}
void update2(int o, int l, int r, int a, int b, int h) {
//这个区间底下包含一个高为h的矩形然后上面是一个三角形,最左侧恰好有h+1个方块
if(a <= l && r <= b) {
lazy[o] += h;
lazy2[o]++;
return;
} else {
push_down(o, l, r);
int m = (l + r) >> 1;
if(a <= m)
update2(o << 1, l, m, a, b, h);
//左侧底下方块是一样的
if(b >= m + 1)
update2(o << 1 | 1, m + 1, r, a, b, h + m - a + 1);
//右侧多m-a+1个方块
}
}
void all_pushdown(int o, int l, int r) {
if(l == r) {
a[l] += lazy[o] + lazy2[o];
} else {
push_down(o, l, r);
int m = (l + r) >> 1;
all_pushdown(o << 1, l, m);
all_pushdown(o << 1 | 1, m + 1, r);
}
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out","w",stdout);
#endif // Yinku
//sieve();
build();
int m=read();
while(m--){
int op=read(),l=read(),r=read();
if(op==1){
int x=read();
update(1,1,1000000,l,r,x);
}
else{
update2(1,1,1000000,l,r,0);
}
}
all_pushdown(1,1,1000000);
ll maxans=a[1];
for(int i=2;i<=1000000;i++){
if(a[i]>maxans)
maxans=a[i];
}
printf("%lld\n",maxans);
}
GXU - 7D - 区间求和 - 前缀和的更多相关文章
- vijos1740 聪明的质监员 (二分、区间求和)
http://www.rqnoj.cn/problem/657 https://www.vijos.org/p/1740 P1740聪明的质检员 请登录后递交 标签:NOIP提高组2011[显示标签] ...
- poj3468树状数组的区间更新,区间求和
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 47174 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- POJ 2823 Sliding Window 线段树区间求和问题
题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- LightOJ 1112 Curious Robin Hood (单点更新+区间求和)
http://lightoj.com/volume_showproblem.php?problem=1112 题目大意: 1 i 将第i个数值输出,并将第i个值清0 2 i v ...
- POJ 3468 A Simple Problem with Integers(线段树区间求和)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...
- D 区间求和 [数学 树状数组]
D 区间求和 题意:求 \[ \sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和 \] 比赛时因为被B卡了没有深入想这道题 结果B没做出来 ...
随机推荐
- css sprite技巧详解
1. [代码][CSS]代码 CSSSprites在国内很多人叫css精灵,是一种网页图片应用处理方式.它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片 ...
- js操作url的常用函数
1. //替换指定传入参数的值,paramName为参数,replaceWith为新值 function replaceParamVal(oUrl,paramName, replaceWith) { ...
- Echarts 地图(map)插件之 鼠标HOVER和tooltip自定义数据
在项目开发中,有需要用到地图的地方,百度的echarts地图插件就是个不错的选择, 这里总结一下地图自定义鼠标HOVER时的事件和自定义tooltip数据: 一.鼠标HOVER时的事件: 参照官方文档 ...
- Chrome_01_点击 Google搜索结果在新的页面打开
方法一:Ctrl + 左键 Chrome浏览器中,通过 Ctrl + 左键 ,是在新标签中打开的,通过 Shift + 左键 ,是在新窗口中打开的. 方法二: 1.登录 Google 2.进入下面的设 ...
- linux命令学习笔记(14):head 命令
head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显 示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. .命令格式: hea ...
- java枚举学习enum
java 1.5以后才出现enum的关键字 所有的enum类都继承自Enum类,所以enum类无法再继承其他的类,可以实现接口,枚举类出了不能被继承其余的与普通类的特性一致, 枚举类的构造函数只能自己 ...
- nvidia-docker 安装
1.安装docker 官方网址安装说明 https://docs.docker.com/install/linux/docker-ce/ubuntu/ 2.ubuntu 14.04/16.04/18. ...
- 制作spark镜像
构建镜像 添加jdk引用(可以使用yum进行安装): 安装SSH 碰到一个问题,执行systemctl的时候发生了异常: Failed to get D-Bus connection 解决这个问题的方 ...
- 洛谷 P4220 & UOJ #347 通道 —— 随机化
题目:https://www.luogu.org/problemnew/show/P4220 http://uoj.ac/problem/347 先写了一下 n^2 和三棵树一样的情况,n^2 还写了 ...
- 上海-北京间通过Azure Storage的RA-GRS类型的存储账户进行快速复制
Azure的Blob存储分成多种类型,目前主要有: 其中RA-GRS可以在上海-北京两个数据中心间同步数据.并且,在第二个数据中心可以只读的方式读取这个存储账户中的Blob内容. 虽然GRS采用的是准 ...