Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend
这题是一个贼搞人的线段树
线段树维护的是 区间和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的更多相关文章
- 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 ...
- Codeforces Round #546 (Div. 2) B. Nastya Is Playing Computer Games
链接:https://codeforces.com/contest/1136/problem/B 题意: 有n个井盖,每个井盖上有一个小石头. 给出n和k,k表示刚开始在第k个井盖上方. 有三种操作, ...
- 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)是遍历过的 ...
- Codeforces Round #546 (Div. 2)-D - Nastya Is Buying Lunch
这道题,神仙贪心题... 题意就是我给出数的顺序,并给出多个交换,每个只能用于相邻交换,问最后一个元素,最多能往前交换多少步. 我们考虑这样一个问题,如果一个这数和a[n]发生交换,那么这个数作为后面 ...
- Codeforces Round #546 (Div. 2) 题解
Codeforces Round #546 (Div. 2) 题目链接:https://codeforces.com/contest/1136 A. Nastya Is Reading a Book ...
- 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\),那 ...
- Codeforces Round #546 (Div. 2)
http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; ; int N, K; ...
- Codeforces Round #546 (Div. 2) E 推公式 + 线段树
https://codeforces.com/contest/1136/problem/E 题意 给你一个有n个数字的a数组,一个有n-1个数字的k数组,两种操作: 1.将a[i]+x,假如a[i]+ ...
- Codeforces Round #546 (Div. 2) D 贪心 + 思维
https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...
随机推荐
- 【转】Linux下从TCP状态机,三次握手判断DDOS攻击
从TCP状态机判断DDOS攻击 一.TCP协议 TCP 协议是传送层的核心协议,提供了可靠面向连接的协议,分为三次握手和四次断开,在这个过程中TCP有个状态机,记录不同阶段的状态. 二. TCP握手和 ...
- FinalShell使用---Xshell的良心国产软件
最近发现了一款同类产品FinalShell,还是一块良心国货.初步体验了一下,确实是良心之作.且免费(通用版),支持国货. FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还 ...
- MySQL运维之--xtrabackup工具的原理和使用方法
Xtrabackup工具的介绍 xtrabackup是percona公司开发的一款自由.免费.开源的一款备份工具,他的备份特点就是:支持热备.备份速度快. xtrabackup包含两个重要的工具:in ...
- shp转oracle spatial
2010年12月1日 终于搞定了shp到oracle spatial,说下步骤和感受吧! 1 XP系统:转换工具的下载(shp2sdo.exe ):下载后把此文件复制到PATH变量包含的目录下(E: ...
- oracle 手动增加序列值
1.select seq_name.nextval from dual; //假设得到结果5656 2.alter sequence seq_name increment by -5655; //注意 ...
- ES6标准入门之正则表达式的拓展
所谓正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式通常被用来检索.替换那些符合某个模式(规 ...
- 解决The SDK platform-tools version ((23)) is too old to check APIs compiled with API 23
用2.0的Android Studio bate版 打开项目,在包名的地方会出现一条红线,但是似乎不影响代码的正确性. 看着好不爽啊,我倒是还没运行就找办法解决掉了.就是说是否影响程序正常运行我是不 ...
- OpenGL笔记(四) API参考
常见API glActiveTexture 选择活动纹理单元 glAttachShader 将一个着色器对象绑定到一个程序对象 void glAttachShader(GLuint program, ...
- jqgrid 设置行编辑为本地端编辑状态
有时,我们需要在jqgrid表格中做编辑操作,而jqgrid默认是启动了行保存连接到服务器更新.此时,如果没有指定editurl的有效url值时会报错 有时,我们需要将编辑完的表格数据一次性提交保存( ...
- linux中原子操作实现方式
原子操作提供了指令原子执行,中间没有中断.就像原子被认为是不可分割颗粒一样,原子操作(atomic operation)是不可分割的操作. 如下面简单的例子: Thread 1 ...