这题是一个贼搞人的线段树

线段树维护的是 区间和a[i - j]

首先对于update的位置可以二分查找

其次update时候的lazy比较技巧

比如更新的是 l-r段,增加的是c

那么这段的值为:

a[l] + c, a[l + 1] + k[l] + c, .... a[r] + k[l] + .. + k[r-1] + c

lazy 记录的是 a[l] + c - (k[1] + ... + k[l - 1])

每次pushdown的时候

a[i]_new = lazy + k_prefix_sum[i-1]

为了方便,我们把所有的k标号都+1

#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <complex>
#include <cassert>
#include <random>
#include <cstring>
#include <numeric>
#define ll long long
#define ld long double
#define null NULL
#define all(a) a.begin(), a.end()
#define forn(i, n) for (int i = 0; i < n; ++i)
#define sz(a) (int)a.size()
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
template<class T> int gmax(T &a, T b) { if (b > a) { a = b; return 1; } return 0; }
template<class T> int gmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }
using namespace std; const int N = 1e5 + 5;
const ll lazyDefault = -1e18; ll a[N];
ll k[N];
ll kSum[N];
ll tree[N << 2];
ll lazy[N << 2]; void pushUp(int rt) {
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
} void pushDown(int rt, int l, int r) {
if(lazy[rt] != lazyDefault) {
int m = (l + r) >> 1;
int lpart = (r - l + 2) / 2;
int rpart = (r - l + 1) / 2; tree[rt << 1] = lpart * lazy[rt] + (kSum[m] - kSum[l - 1]);
tree[rt << 1 | 1] = rpart * lazy[rt] + (kSum[r] - kSum[m]); lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
lazy[rt] = lazyDefault;
}
} void build(int l, int r, int rt) {
lazy[rt] = lazyDefault;
if(l == r) {
tree[rt] = a[l];
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
pushUp(rt);
} ll query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return tree[rt];
}
pushDown(rt, l, r);
ll sum = 0;
int m = (l + r) >> 1;
if(L <= m) sum += query(L, R, lson);
if(R > m) sum += query(L, R, rson);
return sum;
} void update(int L, int R, ll c, int l, int r, int rt) {
if(L <= l && r <= R) {
tree[rt] = (r - l + 1) * c + kSum[r] - kSum[l - 1];
lazy[rt] = c;
return;
}
pushDown(rt, l, r);
int m = (l + r) >> 1;
if(L <= m) update(L, R, c, lson);
if(R > m) update(L, R, c, rson);
pushUp(rt);
} void debug(int l, int r, int rt) {
printf("%d %d %lld\n", l, r, tree[rt]);
if(l == r) return;
pushDown(rt, l, r);
int m = (l + r) >> 1;
debug(lson);
debug(rson);
} int main() {
int n;
while(~scanf("%d", &n)) {
for(int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
} for(int i = 2; i <= n; ++i) {
scanf("%lld", &k[i]);
k[i] += k[i-1];
}
for(int i = 2; i <= n; ++i) {
kSum[i] += kSum[i-1] + k[i];
} build(1,n,1); int q;
scanf("%d", &q);
while(q -- ) {
char s[10]; int x, y;
scanf("%s %d %d", s, &x, &y);
if(s[0] == '+') {
int l = x; int r = n;
ll tmp = query(x, x, 1, n, 1);
while(l <= r) {
int m = (l + r) >> 1;
ll tmp2 = query(m, m, 1, n, 1);
if(tmp2 - tmp - y > k[m] - k[x]) r = m - 1;
else l = m + 1;
}
// printf("choose: %d\n", r);
update(x, r, tmp + y - k[x], 1, n, 1);
} else {
printf("%lld\n", query(x, y, 1, n, 1));
}
// debug(1, n, 1);
}
}
return 0;
}

Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend的更多相关文章

  1. Codeforces Round #546 (Div. 2) C. Nastya Is Transposing Matrices

    C. Nastya Is Transposing Matrices time limit per test 1 second memory limit per test 256 megabytes i ...

  2. Codeforces Round #546 (Div. 2) B. Nastya Is Playing Computer Games

    链接:https://codeforces.com/contest/1136/problem/B 题意: 有n个井盖,每个井盖上有一个小石头. 给出n和k,k表示刚开始在第k个井盖上方. 有三种操作, ...

  3. Codeforces Round #546 (Div. 2) A. Nastya Is Reading a Book

    链接:https://codeforces.com/contest/1136/problem/A 题意: 给n个区间,每个区间范围不超过100,n不超过100. 给一个位置k,1-(k-1)是遍历过的 ...

  4. Codeforces Round #546 (Div. 2)-D - Nastya Is Buying Lunch

    这道题,神仙贪心题... 题意就是我给出数的顺序,并给出多个交换,每个只能用于相邻交换,问最后一个元素,最多能往前交换多少步. 我们考虑这样一个问题,如果一个这数和a[n]发生交换,那么这个数作为后面 ...

  5. Codeforces Round #546 (Div. 2) 题解

    Codeforces Round #546 (Div. 2) 题目链接:https://codeforces.com/contest/1136 A. Nastya Is Reading a Book ...

  6. Nastya Hasn't Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)

    题目链接 传送门 题面 题意 给你一个\(a\)数组和一个\(k\)数组,进行\(q\)次操作,操作分为两种: 将\(a_i\)增加\(x\),此时如果\(a_{i+1}<a_i+k_i\),那 ...

  7. Codeforces Round #546 (Div. 2)

    http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; ; int N, K; ...

  8. Codeforces Round #546 (Div. 2) E 推公式 + 线段树

    https://codeforces.com/contest/1136/problem/E 题意 给你一个有n个数字的a数组,一个有n-1个数字的k数组,两种操作: 1.将a[i]+x,假如a[i]+ ...

  9. Codeforces Round #546 (Div. 2) D 贪心 + 思维

    https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...

随机推荐

  1. 【转】Linux下从TCP状态机,三次握手判断DDOS攻击

    从TCP状态机判断DDOS攻击 一.TCP协议 TCP 协议是传送层的核心协议,提供了可靠面向连接的协议,分为三次握手和四次断开,在这个过程中TCP有个状态机,记录不同阶段的状态. 二. TCP握手和 ...

  2. FinalShell使用---Xshell的良心国产软件

    最近发现了一款同类产品FinalShell,还是一块良心国货.初步体验了一下,确实是良心之作.且免费(通用版),支持国货. FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还 ...

  3. MySQL运维之--xtrabackup工具的原理和使用方法

    Xtrabackup工具的介绍 xtrabackup是percona公司开发的一款自由.免费.开源的一款备份工具,他的备份特点就是:支持热备.备份速度快. xtrabackup包含两个重要的工具:in ...

  4. shp转oracle spatial

    2010年12月1日  终于搞定了shp到oracle spatial,说下步骤和感受吧! 1 XP系统:转换工具的下载(shp2sdo.exe ):下载后把此文件复制到PATH变量包含的目录下(E: ...

  5. oracle 手动增加序列值

    1.select seq_name.nextval from dual; //假设得到结果5656 2.alter sequence seq_name increment by -5655; //注意 ...

  6. ES6标准入门之正则表达式的拓展

    所谓正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式通常被用来检索.替换那些符合某个模式(规 ...

  7. 解决The SDK platform-tools version ((23)) is too old to check APIs compiled with API 23

    用2.0的Android Studio  bate版 打开项目,在包名的地方会出现一条红线,但是似乎不影响代码的正确性. 看着好不爽啊,我倒是还没运行就找办法解决掉了.就是说是否影响程序正常运行我是不 ...

  8. OpenGL笔记(四) API参考

    常见API glActiveTexture 选择活动纹理单元 glAttachShader 将一个着色器对象绑定到一个程序对象 void glAttachShader(GLuint program, ...

  9. jqgrid 设置行编辑为本地端编辑状态

    有时,我们需要在jqgrid表格中做编辑操作,而jqgrid默认是启动了行保存连接到服务器更新.此时,如果没有指定editurl的有效url值时会报错 有时,我们需要将编辑完的表格数据一次性提交保存( ...

  10. linux中原子操作实现方式

    原子操作提供了指令原子执行,中间没有中断.就像原子被认为是不可分割颗粒一样,原子操作(atomic operation)是不可分割的操作. 如下面简单的例子: Thread 1             ...