题目链接

传送门

题面



题意

给你一个\(a\)数组和一个\(k\)数组,进行\(q\)次操作,操作分为两种:

  • 将\(a_i\)增加\(x\),此时如果\(a_{i+1}<a_i+k_i\),那么就将\(a_{i+1}\)变成\(a_i+k_i\),如果\(a_{i+2}<a_i+k_i\),则将\(a_{i+2}\)变成\(a_{i+1}+k_{i+1}\),以此类推。
  • 查询\(\sum\limits_{i=l}^{r}a_i\)。

思路

我们首先存下\(k\)数组的前缀和\(sum1\),再存\(sum1\)的前缀和\(sum2\)。

那么修改操作产生的影响我们就可以先通过二分出右端点\(r\),然后进行区间覆盖,将\([l,r]\)覆盖成\(a_i\),然后这一段区间的\(sum=a_i\times (r-l+1)+sum2[r]-sum2[l]-sum1[l]\times(r-l)\)。

查询操作就是普通的区间求和。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; char op[3];
int n, q, l, r;
LL sum1[maxn], sum2[maxn];
int k[maxn]; struct node {
bool lazy;
int l, r;
LL val, sum;
}segtree[maxn<<2]; void push_up(int rt) {
segtree[rt].sum = segtree[lson].sum + segtree[rson].sum;
} void push_down(int rt) {
if(!segtree[rt].lazy) return;
segtree[rt].lazy = 0;
segtree[lson].lazy = segtree[rson].lazy = 1;
segtree[lson].val = segtree[rt].val;
segtree[rson].val = sum1[segtree[rson].l] - sum1[segtree[rt].l] + segtree[rt].val;
segtree[lson].sum = segtree[lson].val * (segtree[lson].r - segtree[lson].l + 1) + sum2[segtree[lson].r] - sum2[segtree[lson].l] - sum1[segtree[lson].l] * (segtree[lson].r - segtree[lson].l);
segtree[rson].sum = segtree[rson].val * (segtree[rson].r - segtree[rson].l + 1) + sum2[segtree[rson].r] - sum2[segtree[rson].l] - sum1[segtree[rson].l] * (segtree[rson].r - segtree[rson].l);
} void build(int rt, int l, int r) {
segtree[rt].l = l, segtree[rt].r = r;
segtree[rt].sum = segtree[rt].lazy = 0;
if(l == r) {
scanf("%lld", &segtree[rt].val);
segtree[rt].sum = segtree[rt].val;
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
push_up(rt);
} void update1(int rt, int pos, int x) {
if(segtree[rt].l == segtree[rt].r) {
segtree[rt].val += x;
segtree[rt].sum += x;
return;
}
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(pos <= mid) update1(lson, pos, x);
else update1(rson, pos, x);
push_up(rt);
} void update2(int rt, int l, int r, LL x) {
if(segtree[rt].l == l && segtree[rt].r == r) {
segtree[rt].val = x;
segtree[rt].lazy = 1;
segtree[rt].sum = x * (r - l + 1) + sum2[r] - sum2[l] - sum1[l] * (r - l);
return;
}
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) update2(lson, l, r, x);
else if(l > mid) update2(rson, l, r, x);
else {
update2(lson, l, mid, x);
update2(rson, mid + 1, r, x + sum1[mid + 1] - sum1[l]);
}
push_up(rt);
} LL query1(int rt, int pos) {
if(segtree[rt].l == segtree[rt].r) return segtree[rt].val;
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(pos <= mid) return query1(lson, pos);
else return query1(rson, pos);
} LL query2(int rt, int l, int r) {
if(segtree[rt].l == l && segtree[rt].r == r) {
return segtree[rt].sum;
}
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) return query2(lson, l, r);
else if(l > mid) return query2(rson, l, r);
else return query2(lson, l, mid) + query2(rson, mid + 1, r);
} int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &n);
build(1, 1, n);
for(int i = 1; i < n; ++i) {
scanf("%d", &k[i]);
}
for(int i = 2; i <= n; ++i) {
sum1[i] = sum1[i-1] + k[i-1];
}
for(int i = 2; i <= n; ++i) {
sum2[i] = sum2[i-1] + sum1[i];
}
scanf("%d", &q);
while(q--) {
scanf("%s%d%d", op, &l, &r);
if(op[0] == '+') {
int ub = n, lb = l + 1, mid, ans = -1;
update1(1, l, r);
LL val = query1(1, l);
while(ub >= lb) {
mid = (ub + lb) >> 1;
if(query1(1, mid) < val + sum1[mid] - sum1[l]) {
ans = mid;
lb = mid + 1;
} else {
ub = mid - 1;
}
}
if(ans != -1) update2(1, l, ans, val);
} else {
printf("%lld\n", query2(1, l, r));
}
}
return 0;
}

最新文章

  1. John the ripper使用教程
  2. MMORPG大型游戏设计与开发(服务器 AI 基础接口)
  3. Oracle学习系列5
  4. Nginx学习笔记(九) 配置文件详细说明
  5. webservice basics
  6. .NET去掉HTML标记
  7. MVC学习系列——Model验证扩展
  8. wpf 中DataGrid 控件的样式设置及使用
  9. cf C. Dominoes
  10. ZJOI2017 Day3 滚粗记
  11. ubuntu12.04 安装中文输入法
  12. python-memcached学习笔记
  13. ubuntu 通过apt安装jdk
  14. jmap MAT内存溢出实践
  15. 编译安装mysql5.7
  16. python-标识符(Identifiers)和关键字(keywords)
  17. mybatis调用存储过程获得取返回值
  18. 制作Solaris系统的USB启动盘
  19. linux shell 学习笔记--比较操作
  20. 随机生成一份试卷,试卷的种类分为单选、多选、判断三种题型。nodejs6.0 mysql

热门文章

  1. idea内置tomcat中java代码热更新
  2. 类型的实参与“LPTHREAD_START_ROUTINE”类型的形参不兼容
  3. SpringBootSecurity学习(07)网页版登录整合JDBC
  4. 使用 ProcessMonitor 找到进程所操作的文件的路径
  5. Excel表格快速将公式运用到一整列
  6. Linux系统新手入门学习的四点建议
  7. 在Centos6.5上部署kvm虚拟化技术
  8. kali之DVWA
  9. ConnectionString属性(网速慢的情况下研究Connect Timeout)
  10. Shallow copy and Deep copy