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 - 区间求和 - 前缀和的更多相关文章

  1. vijos1740 聪明的质监员 (二分、区间求和)

    http://www.rqnoj.cn/problem/657 https://www.vijos.org/p/1740 P1740聪明的质检员 请登录后递交 标签:NOIP提高组2011[显示标签] ...

  2. poj3468树状数组的区间更新,区间求和

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 47174   ...

  3. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  4. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

  5. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  6. LightOJ 1112 Curious Robin Hood (单点更新+区间求和)

    http://lightoj.com/volume_showproblem.php?problem=1112 题目大意: 1 i        将第i个数值输出,并将第i个值清0 2 i v     ...

  7. 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 ...

  8. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

    转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...

  9. D 区间求和 [数学 树状数组]

    D 区间求和 题意:求 \[ \sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和 \] 比赛时因为被B卡了没有深入想这道题 结果B没做出来 ...

随机推荐

  1. Python- and & or 的短路原则

    条件1 and 条件2 条件1 or 条件2 短路原则 对于and 如果前面的第一个条件为假,那么这个and前后两个条件组成的表达式的计算结果就一定为假,第二个条件就不会被计算 对于or 如果前面的第 ...

  2. codeforces 615E Hexagons (二分+找规律)

    E. Hexagons time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  3. tbody scroll

    http://jsfiddle.net/hashem/CrSpu/555/

  4. NYOJ-求逆序数 ----------------待解决,WA

    描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数 ...

  5. 苹果公司CEO乔布斯在斯坦福大学毕业典礼上的演讲

    苹果公司CEO乔布斯在斯坦福大学毕业典礼上的演讲 摘要:这是苹果公司CEO乔布斯2005年在斯坦福大学毕业典礼上的演讲,大学途中退学,创业,被解雇,东山再起,死亡威胁,这些他都一一经历了.经营自己与众 ...

  6. jquery.cxSelect插件,城市没单位

    jquery.cxSelect插件,新增城市没单位也能显示出来的功能. 具体,请查看修改后的插件代码:(主要是FixNoUnit函数) /*! * jQuery cxSelect * @name jq ...

  7. Impala的JDBC无法连接

    这是因为客户端连接的JDBC是Impala的master机器,而不是DataNode:因为JDBC的服务宿主是Impalad,而Impalad只是部署在DataNode

  8. androidpn环境搭建

    1.下载androidpn版本.http://sourceforge.net/projects/androidpn/postdownload?source=dlp 2.下载安装tomcat 2.1 下 ...

  9. 微服务理论之六:ESB与SOA的关系

    一.SOA和ESB一直是没有明确概念的两个缩略词 SOA----面向服务架构,实际上强调的是软件的一种架构,一种支撑软件运行的相对稳定的结构,表面含义如此,其实SOA是一种通过服务整合来解决系统集成的 ...

  10. AD9各种布线总结

    1.常规布线:不详细说了,是个人就知道怎么弄.需要说明的是在布线过程中,可按小键盘的*键或大键盘的数字2键添加一个过孔:按L键可以切换布线层:按数字3可设定最小线宽.典型线宽.最大线宽的值进行切换. ...