codeforces 1136E-Nastya Hasn't Written a Legend
传送门:QAQQAQ
题意:有一个数组a和一个数组k,数组a一直保持一个性质:a[i + 1] >= a[i] + k[i]。有两种操作:1,给某个元素加上x,但是加上之后要保持数组a的性质。比如a[i]加上x之后,a[i + 1]<a[i] + k[i],那么a[i + 1]就变成a[i] + k[i],否则不变。同理,若a[i + 2]小于了现在的a[i + 1] + k[i + 1],那么a[i + 2]也变成a[i + 1] + k[i + 1],一直保持这个性质。第二章操作,询问数组a的区间[l, r]的区间和。
思路:用另一个b数组保存a[i]-(k[1]+k[2]+...+k[i-1]),这样由题意的大小关系可知,b数组是非递减的。所以更新是只需在b[x]加上y用二分找出一段连续的需要被修改的区间即可,为节省时间,k应该用前缀和形式保存。
查询时,只需利用b数组建造线段树并维护,求区间sum并加上之前每个b[i]被减掉的k即可,为节省时间,可以再前缀和k的基础上再加一个前缀和kk。这样查询时只需求query(1,1,n,l,r)+kk[r-1]-kk[l-2]。
注意:b数组只在建线段树时用到,因为后面b不再被更新,需要用query求出最新的b数组里的值; 赋值懒标记tag时一定要赋值成数据无法触碰到的值INF,否则会出现无法pushdown的情况(之前赋值成-1,在第7个点上调了老半天)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
const ll inf=-1e18; ll n,a[N],b[N],k[N],kk[N],m; ll sum[N<<],tag[N<<];
void build(int x,int l,int r)
{
if(l==r)
{
sum[x]=b[l];
return;
}
int mid=(l+r)>>;
build(x+x,l,mid);
build(x+x+,mid+,r);
sum[x]=sum[x+x]+sum[x+x+];
} void push_down(int x,int l,int r)
{
int mid=(l+r)>>;
if(tag[x]==inf) return;
tag[x+x]=tag[x]; tag[x+x+]=tag[x];
sum[x+x]=tag[x]*(mid-l+);
sum[x+x+]=tag[x]*(r-mid);
tag[x]=inf;
} void update(int x,int l,int r,int L,int R,ll val)
{
if(L<=l&&r<=R)
{
tag[x]=val;
sum[x]=val*(r-l+);
return;
}
int mid=(l+r)>>;
push_down(x,l,r);
if(mid>=R) update(x+x,l,mid,L,R,val);
else if(mid<L) update(x+x+,mid+,r,L,R,val);
else
{
update(x+x,l,mid,L,R,val);
update(x+x+,mid+,r,L,R,val);
}
sum[x]=sum[x+x]+sum[x+x+];
} ll query(int x,int l,int r,int L,int R)
{
if(L>R) return ;
if(L<=l&&r<=R) return sum[x];
int mid=(l+r)>>;
push_down(x,l,r);
if(mid>=R) return query(x+x,l,mid,L,R);
else if(mid<L) return query(x+x+,mid+,r,L,R);
else
{
return query(x+x,l,mid,L,R)+query(x+x+,mid+,r,L,R);
}
} int main()
{
for(int i=;i<(N<<);i++) tag[i]=inf;
scanf("%lld",&n);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
for(int i=;i<n;i++) scanf("%lld",&k[i]);
for(int i=;i<n;i++) k[i]+=k[i-];
for(int i=;i<n;i++) kk[i]=kk[i-]+k[i];
for(int i=;i<=n;i++) b[i]=a[i]-k[i-];//feidijian
build(,,n);
scanf("%lld",&m);
while(m--)
{
char s[]; int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[]=='s')
{
ll add=kk[y-]-(x>= ? kk[x-] : );
printf("%lld\n",add+query(,,n,x,y));
}
else
{
ll num=query(,,n,x,x)+y;//can't write b[x] instead of query(1,1,n,x,x)
//int pos=lower_bound(b,b+n+1,num)-b;
//can't use array b!
int l=x,r=n,mid,pos=x;
while(l<=r)
{
mid=(l+r)>>;
if(num>query(,,n,mid,mid))
{
pos=mid;
l=mid+;
}
else r=mid-;
}
update(,,n,x,pos,num);
}
}
return ;
}
codeforces 1136E-Nastya Hasn't Written a Legend的更多相关文章
- codeforces#1136E. Nastya Hasn't Written a Legend(二分+线段树)
题目链接: http://codeforces.com/contest/1136/problem/E 题意: 初始有a数组和k数组 有两种操作,一,求l到r的区间和,二,$a_i\pm x$ 并且会有 ...
- Codeforces 1136E - Nastya Hasn't Written a Legend - [线段树+二分]
题目链接:https://codeforces.com/problemset/problem/1136/E 题意: 给出一个 $a[1 \sim n]$,以及一个 $k[1 \sim (n-1)]$, ...
- Codeforces 1136E Nastya Hasn't Written a Legend 线段树
vp的时候没码出来.. 我们用set去维护, 每一块区域, 每块区域内的元素与下一个元素的差值刚好为ki,每次加值的时候我们暴力合并, 可以发现我们最多合并O(n)次. 然后写个线段树就没了. #in ...
- Codeforces 1136E Nastya Hasn't Written a Legend (线段树教做人系列)
题意:有一个数组a和一个数组k,数组a一直保持一个性质:a[i + 1] >= a[i] + k[i].有两种操作:1,给某个元素加上x,但是加上之后要保持数组a的性质.比如a[i]加上x之后, ...
- Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend
这题是一个贼搞人的线段树 线段树维护的是 区间和a[i - j] 首先对于update的位置可以二分查找 其次update时候的lazy比较技巧 比如更新的是 l-r段,增加的是c 那么这段的值为: ...
- 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\),那 ...
- cf1136E. Nastya Hasn't Written a Legend(二分 线段树)
题意 题目链接 Sol yy出了一个暴躁线段树的做法. 因为题目保证了 \(a_i + k_i <= a_{i+1}\) 那么我们每次修改时只需要考虑取max就行了. 显然从一个位置开始能影响到 ...
- CF1136E Nastya Hasn't Written a Legend(线段树)
还能说什么呢,简直太妙了. $$a_{i+1}<a_i+k_i$$ $$a_{i+1}-k_i-k_{i-1}-\cdots-k_1<a_i+k_i-k_i-k_{i-1}-\cdots- ...
- codeforces 1136E 线段树
codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...
随机推荐
- USACO2006 Backward Digit Sums /// 全排列 oj24212
题目大意: 给出杨辉三角的顶点值M和底边数的个数 N (1 ≤ N ≤ 10) ,求出底边各个数的值,其中各个数范围都为1 ~ N 当N=4,M=16时可能是这样的 3 1 2 4 ...
- CentOS7开放防火墙端口
~~~~~~~~~~~~开放某个端口~~~~~~~~~~~~firewall-cmd --zone=public --add-port=6669/tcp --permanentfirewall-cmd ...
- python2x 安装 psutil
安装psutil模块: wget https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz --no-check-cer ...
- 关于jquery.validate.js的用法
// 手机号码验证 jQuery.validator.addMethod("isMobile", function(value, element) { var length = ...
- undertow服务器
参考地址:http://undertow.io/undertow-docs/undertow-docs-1.3.0/index.html 1.引入相关jar <dependencies> ...
- 最大流Dinic算法的一些优化 [网络流][最大流]
明天省夏要讲网络流啦!晚上翻出自己的模板发现是蓝书模板QwQ..拿出以前的提交代码(AC过的?) 曾经的提交记录 在luogu上重新提交一遍,结果gg...OVO 没有去除多余的inline 去除了多 ...
- csps模拟86异或,取石子,优化题解
题面:https://www.cnblogs.com/Juve/articles/11736440.html 异或: 考试时只想出了暴力 我们可以对于二进制下每一位w,求出[l,r]中有几个数在这一位 ...
- 学习Caffe(一)使用Caffe
如何使用Caffe Caffe教程(http://robots.princeton.edu/courses/COS598/2015sp/slides/Caffe/caffe_tutorial.pdf) ...
- 关于Delphi中的字符串的详细分析
关于Delphi中的字符串的详细分析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(S ...
- idea的安装与破解
1.下载 官网:https://www.jetbrains.com/idea/download/#section=windows 百度盘:https://pan.baidu.com/s/16mRNPK ...