题目大意:NOIP2018d1t1 支持 M 次区间查询答案和区间修改操作。

题解:

首先考虑不带区间修改的情况。从左到右进行考虑,发现对于第 i 个数来说,对答案的贡献仅仅取决于第 i-1 个数的大小:若 \(a_i \le a_{i-1}\),则第 i 个数对答案的贡献为 0,否则对答案的贡献为两者的差值。贡献可以这样算是因为每个点至少增加 \(a_i\) 次,且当前点增加多少仅对后面一个数有直接影响。因此,考虑维护差分数组即可,区间修改变成两次单点修改,区间查询转变成查询区间大于 0 的数字之和。则每次询问 [l,r] 的答案为:sum[l+1,r] + a[l],a[l] 利用树状数组维护差分序列即可单点回答了。时间复杂度为 \(O(MlogN)\)。

代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
typedef long long LL; int n,m,a[maxn],d[maxn];
LL bit[maxn];
void update(int pos,LL val){
for(int i=pos;i<=n;i+=i&-i)bit[i]+=val;
}
LL get(int pos){
LL ret=0;
for(int i=pos;i;i-=i&-i)ret+=bit[i];
return ret;
}
struct node{
#define ls(o) t[o].lc
#define rs(o) t[o].rc
int lc,rc;LL sum;
}t[maxn<<1];
int tot,rt;
void up(int o){
LL suml=t[ls(o)].sum>=0?t[ls(o)].sum:0;
LL sumr=t[rs(o)].sum>=0?t[rs(o)].sum:0;
t[o].sum=suml+sumr;
}
void build(int &o,int l,int r){
o=++tot;
if(l==r){t[o].sum=d[l];return;}
int mid=l+r>>1;
build(ls(o),l,mid),build(rs(o),mid+1,r);
up(o);
}
void modify(int o,int l,int r,int pos,int val){
if(l==r){t[o].sum+=val;return;}
int mid=l+r>>1;
if(pos<=mid)modify(ls(o),l,mid,pos,val);
else modify(rs(o),mid+1,r,pos,val);
up(o);
}
LL query(int o,int l,int r,int x,int y){
if(l==x&&r==y)return max(t[o].sum,0LL);
int mid=l+r>>1;
if(y<=mid)return query(ls(o),l,mid,x,y);
else if(x>mid)return query(rs(o),mid+1,r,x,y);
else return query(ls(o),l,mid,x,mid)+query(rs(o),mid+1,r,mid+1,y);
} void read_and_parse(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=2;i<=n;i++)d[i]=a[i]-a[i-1];
build(rt,1,n);
}
void solve(){
int opt,l,r,val;
while(m--){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d",&l,&r,&val);
modify(rt,1,n,l,val),update(l,val);
if(r!=n)modify(rt,1,n,r+1,-val),update(r+1,-val);
}else{
scanf("%d%d",&l,&r);
LL ret=l==r?0:query(rt,1,n,l+1,r);
printf("%lld\n",ret+get(l)+a[l]);
}
}
}
void init(){
tot=rt=0;
for(int i=1;i<=n;i++)bit[i]=0;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
init();
read_and_parse();
solve();
}
return 0;
}

【The 13th Chinese Northeast Collegiate Programming Contest H 题】的更多相关文章

  1. 【The 13th Chinese Northeast Collegiate Programming Contest E题】

    题目大意:给定一棵 N 个点的树,边有边权,定义"线树"为一个图,其中图的顶点是原树中的边,原树中两条有公共端点的边对应在线图中存在一条边,边权为树中两条边的边权和,求线图的最小生 ...

  2. The 13th Chinese Northeast Collegiate Programming Contest(B C E F H J)

    B. Balanced Diet 思路:把每一块选C个产生的价值记录下来,然后从小到大枚举C. #include<bits/stdc++.h> using namespace std; ; ...

  3. The 13th Chinese Northeast Collegiate Programming Contest

    题解: solution Code: A. Apple Business #include<cstdio> #include<algorithm> #include<ve ...

  4. The 2015 China Collegiate Programming Contest H. Sudoku hdu 5547

    Sudoku Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...

  5. Gym 100952H&&2015 HIAST Collegiate Programming Contest H. Special Palindrome【dp预处理+矩阵快速幂/打表解法】

    H. Special Palindrome time limit per test:1 second memory limit per test:64 megabytes input:standard ...

  6. 2015 HIAST Collegiate Programming Contest H

    A sequence of positive and non-zero integers called palindromic if it can be read the same forward a ...

  7. The 13th Zhejiang Provincial Collegiate Programming Contest - I

    People Counting Time Limit: 2 Seconds      Memory Limit: 65536 KB In a BG (dinner gathering) for ZJU ...

  8. The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)

    传送门 •题意 二维平面上有 n 条线段,每条线段坐标为 $(l_i,i),(r_i,i)$: 平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同: 问最多有多少条线段可以放 ...

  9. ZOJ 3946.Highway Project(The 13th Zhejiang Provincial Collegiate Programming Contest.K) SPFA

    ZOJ Problem Set - 3946 Highway Project Time Limit: 2 Seconds      Memory Limit: 65536 KB Edward, the ...

随机推荐

  1. 【学习笔记】adb命令

    1.adb connect 连接设备 如:adb connect 127.0.0.1:62001 连接夜神模拟器\adb connect 127.0.0.1:21503 链接逍遥模拟器 adb con ...

  2. caoz的梦呓:所谓打破信息不对称,其实是一种幻觉

    猫宁!!! 参考链接:https://mp.weixin.qq.com/s/UzSyrhe0Vck7ItN-XU6JEg 很多创业者说,要建立怎样一个平台,要打破信息不对称,大部分时候,我都会泼冷水, ...

  3. postman Tests断言

    摘要:关于postman的断言方法很多,在网上随便搜寻下,能搜出一大推,什么牛鬼蛇神都有,让人眼花缭乱..甚至在应用时出现错误.Test断言都是根据js规则来写的,对于我这种不懂js语言的来说确实不友 ...

  4. elasticsearch的备份和恢复(转)

    vim /etc/elasticsearch/elasticsearch.yml path.repo: ["/data/backups/es_backup"] #备份目录,根据自己 ...

  5. (转)C++ bitset用法

    今天做题发现要用到bitset,找到一篇介绍的巨好的文章. 转载自:https://www.cnblogs.com/magisk/p/8809922.html C++的 bitset 在 bitset ...

  6. Python学习【day01】- Python初识

    Python下载:https://www.python.org/downloads/ 下载后进行安装,安装后的Python我们称之为Python解析器 1.打印“Hello World” 安装后的Py ...

  7. PreparedStatement 以及事务的注意事项

    a).PreparedStatement 可以进行批量操作,但是与Statement有一定的区别 1. Statement可以进行不同sql语句的批量操作 即可以同时进行 crud 操作. Strin ...

  8. C++多线程基础学习笔记(三)

    一.detach()大坑 上一篇随笔(二)中提到detach()是用来分离主线程和子线程的,那么需要考虑一个问题,就是如果主线程跑完了,主线程中定义的变量就会被销毁(释放内存),这时回收变量仍作为参数 ...

  9. springboot读取配置不存在报错

    @Value("${log.regId}")private String regId = "123123"; String regId = env.getPro ...

  10. Arkady and a Nobody-men CodeForces - 860E (虚树)

    大意: 给定有根树, 根节点深度为$1$. 定义$r(a,b)$为$b$子树内深度不超过$a$的节点数$-1$ 定义$z_a$为$a$的所有祖先的$r$之和. 对于所有点求出$z$的值. 一个点$y$ ...