题目大意: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. Linux下python安装升级详细步骤 | Python2 升级 Python3 转载

    Linux下python升级步骤  Python2 ->Python3 多数情况下,系统自动的Python版本是2.x 或者yum直接安装的也是2.x 但是,现在多数情况下建议使用3.x 那么如 ...

  2. react中setState用法

    setState()更新状态的2种写法 setState(updater, [callback]), updater为返回stateChange对象的函数: (state, props) => ...

  3. 【AMAD】betamax -- 一个ruby-VCR的模仿品,只支持requests

    简介 动机 作用 用法 个人评分 简介 betamax1会记录你的HTTP操作,可以让你在测试的时候不必重复进行真实的请求. 动机 如果你的代码需要和外部资源一起运作,那么测试这段代码的方法就叫做集成 ...

  4. ubuntu 16.04 server 扩容(LVM)磁盘

    因为发现我的本地server出现磁盘满了的情况 所以进行lvm的扩容 1 查看磁盘情况 df -h 原本发现 /dev/mapper/ubuntu1604--vg-root 这个磁盘满了 所以要进行扩 ...

  5. ORACLE 更新 和 插入多条 数据

    --插入语句INSERT INTO OA_W_BAOXIAOMXYWB (ID,DONGTAITABLEPARENTSN,CHANPINNAMEGKFK,CHANPINJITIGKFK,CHANPIN ...

  6. [转帖]Docker常用命令总结

    Docker常用命令总结 http://www.ha97.com/5546.html 发表于: Linux, 互联网, 虚拟化与云计算 | 作者: 博客教主 标签: docker,常用命令,总结 PS ...

  7. codeforces 620C

    题目链接:https://codeforces.com/problemset/problem/620/C 题目分析 题意:给你一串珍珠,每个珍珠都有一个对应值,需要分割这n个珍珠(必须连续),使得每一 ...

  8. C++ 数组操作符重载、函数对象分析、赋值操作符

    string类型访问单个字符 #include <iostream> #include <string> #include <sstream> using name ...

  9. 浅析HBase:为高效的可扩展大规模分布式系统而生

    什么是HBase Apache HBase是运行在Hadoop集群上的数据库.为了实现更好的可扩展性(scalability),HBase放松了对ACID(数据库的原子性,一致性,隔离性和持久性)的要 ...

  10. 如何在万亿级别规模的数据量上使用Spark

    一.前言 Spark作为大数据计算引擎,凭借其快速.稳定.简易等特点,快速的占领了大数据计算的领域.本文主要为作者在搭建使用计算平台的过程中,对于Spark的理解,希望能给读者一些学习的思路.文章内容 ...