题目大意: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. Go package(2) strings 用法

    go version go1.10.3 Go中的字符串用法,可以在 godoc.org 上查看语法和用法. 最简单的语法就是获取字符串中的子串 s := "hello world" ...

  2. mybatis-generator自动生成代码时,只生成insert方法

    今天使用mybatis-generator自动生成代码时,发现只能生成insert方法, 以前所有的方法都是可以生成的,查看网上解决办法和检查数据库表结构后, 发现2种可以解决的办法: 1.修改myb ...

  3. PHP 註解規則使用方式

    /** * 函數名稱 * 函數描述(有些會含HTML代碼) * * @access 變數可存取的權限 (Example: Public or Private) * @api 爲第三方來源的變數 * @ ...

  4. Windows-T

    查看Windows系统版本号 同时按下Windows键和字母R键,然后输入winver就可以了 命令行运行计算器cmd-calc win10卸载XShell6报错1603 在运行里输入regedit打 ...

  5. Unreal Engine 4 优化教程

    本教程旨在帮助开发人员提升基于虚幻引擎(Unreal Engine*4 (UE4))开发的游戏性能.在教程中,我们对引擎内部及外部使用的一系列工具,以及面向编辑器的最佳实践加以概述,还提供了有助于提高 ...

  6. flask 之(三) --- 筛选|分页|过滤

    筛选 查询数据筛选语法:类名.query.筛选符 .all( ):获取结果集:.count( ):获取查询到的对象数量 类名.query.filter(类名.属性.运算符('xxx')).all() ...

  7. PJzhang:python基础入门的7个疗程-six

    猫宁!!! 参考链接:易灵微课-21天轻松掌握零基础python入门必修课 https://www.liaoxuefeng.com/wiki/1016959663602400 第16天:开源模块 sy ...

  8. CentOS下Subversion(SVN)的快速安装与配置

    如果你是一个软件开发者,你一定对Subversion不会感到陌生.Subversion是一个自由开源的版本控制系统.在Subversion管理下,文件和目录可以超越时空.Subversion将文件存放 ...

  9. 编写java 程序与Linux进行远程连接并运行linux下的脚本

    我这里是通过连接到centos6.5的大数据集群的主节点,并通过运行hadoop的启动脚本来启动hadoop 本人采用的是SSH的方式连接 通过创建maven项目来编写代码,在编写代码之前需要先导入架 ...

  10. [转帖]备忘:CentOS-7 使用systemctl 管理的服务,文件打开数上限1024要改

    备忘:CentOS-7 使用systemctl 管理的服务,文件打开数上限1024要改 https://blog.csdn.net/toontong/article/details/50440272 ...