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

线段树维护的是 区间和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. [Spark RDD_1] RDD 基本概念

    0. 说明 RDD 概述 && 创建 RDD 的方式 && RDD 编程 API(Transformation 和 Action Operations) &&a ...

  2. windows的一些好用命令-自己总结:

    在win+R运行框中:     cmd:进入命令行界面     msconfig:可以查看“系统配置”     msinfo32:查看系统信息     services.msc打开"服务&q ...

  3. VS创建工程出错解决方案

    今天在用VS2010创建工程时出现错误:“ 此模板尝试加载组件程序集 “NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, Pu ...

  4. 如何删除sharepoint列表List中的全部数据。

    可以使用excel,但是powershell会比较方便 (admin mode - Sharepoint powershell) [System.reflection.Assembly]::LoadW ...

  5. String、StringBuffer与StringBuilder的区别-陈远波

    String Stringbuffer  StringBuilder的区别: 1.string是字符串常量,且长度是不可改变的,Stringbuffer.stringBuilder是字符串变量 2.S ...

  6. DOM相关方法,属性整理

    DOM相关方法,属性整理1.获取元素的方法 1根据id获取对象 document.getElementById(''); 2根据标签名获取对象 document.getElementsByTagNam ...

  7. facebook api & oauth protocal

    http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-10.5 http://stackoverflow.com/questions/14 ...

  8. python第三十四课——1.匿名函数的定义和使用

    演示匿名函数的定义和使用 # 定义无参有返回值的有名函数: def func(): return True # 定义无参有返回值的匿名函数 f=lambda : True # 调用有名函数执行 pri ...

  9. Vue入门1

    欢迎转载,转载请注明出处. 前言 学习本系列Vue知识,需要结合本系列的一些demo.你可以查看我的 Github 或者直接下载 ZIP包 . 建议学习本系列之前已经会一个其他的前端框架,了解计算属性 ...

  10. Python2.7-pickle, cpickle

    pickle, cpickle模块,用于序列化和反序列化 python 对象数据,可以被序列化的有:布尔值,数值,字符串,包含以上三类的容器,定义在模块顶层的函数.内置函数和类,实例对象的 __dic ...