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<=个交换法则, ...
随机推荐
- [转]Redis学习---Redis高可用技术解决方案总结
[原文]https://www.toutiao.com/i6591646189714670093/ 本文主要针对Redis常见的几种使用方式及其优缺点展开分析. 一.常见使用方式 Redis的几种常见 ...
- oracle数据库中如何去除空格
目前,我所知道的就有两种方法: 一.trim(a)--只能去除字符串左右的空格 select trim(leading from ' ——11—— ') aa from dual; select tr ...
- .Net使用163smtp发送邮件时错误:邮箱不可用. has no permission解决方法
C#实现简单邮件发送代码如下 public static void SendAsync(string emailTo, string subject, string mailBody) { var m ...
- numpy 的排序
import numpy as np # 1.快速排序 ''' 1.np.sort(),不改变原先值的顺序,但是在运行时占内存 2.ndarry.sort(),改变原先值的顺序,不占用内存 ''' # ...
- gcd以及exgcd入门讲解
gcd就是最大公约数,gcd(x, y)一般用(x, y)表示.与此相对的是lcm,最小公倍数,lcm(x, y)一般用[x, y]表示. 人人都知道:lcm(x, y) = x * y / gcd( ...
- css里颜色的那些事儿(合法颜色值)
css中主要有六种方法指定颜色: 1.十六进制颜色 2.RGB颜色 3.RGBA颜色 4.HSL色彩 5.HSLA颜色 6.预定义/跨浏览器的颜色名称 前三种是我们最常见的,也是用的最多的,而后三种对 ...
- Docker技术入门与实战 第二版-学习笔记-5-容器-命令及限制内存与cpu资源
1.启动容器 启动容器有两种方式: 基于镜像新建一个容器并启动 将在终止状态(stopped)的容器重新启动 1)新建并启动——docker run 比如在启动ubuntu:14.04容器,并输出“H ...
- vagrant特性——基于docker开发环境(docker和vagrant的结合)-4-简单例子-有问题
运行一个十分简单的例子: Vagrant.configure() do |config| config.vm.provider "docker" do |d| d.image = ...
- ICC2 常用命令
1. 关于 data preparation : report_ref_libs : report reference library report_lib lib_aa : report the ...
- Perl 杂记
1. Perl 变量: 创建变量是以 $ 开头,比如定义一个变量: $val = "Good job !" 2. Perl 控制流 if 语法: if ( ) { },注意if ...