传送门: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的更多相关文章

  1. codeforces#1136E. Nastya Hasn't Written a Legend(二分+线段树)

    题目链接: http://codeforces.com/contest/1136/problem/E 题意: 初始有a数组和k数组 有两种操作,一,求l到r的区间和,二,$a_i\pm x$ 并且会有 ...

  2. Codeforces 1136E - Nastya Hasn't Written a Legend - [线段树+二分]

    题目链接:https://codeforces.com/problemset/problem/1136/E 题意: 给出一个 $a[1 \sim n]$,以及一个 $k[1 \sim (n-1)]$, ...

  3. Codeforces 1136E Nastya Hasn't Written a Legend 线段树

    vp的时候没码出来.. 我们用set去维护, 每一块区域, 每块区域内的元素与下一个元素的差值刚好为ki,每次加值的时候我们暴力合并, 可以发现我们最多合并O(n)次. 然后写个线段树就没了. #in ...

  4. Codeforces 1136E Nastya Hasn't Written a Legend (线段树教做人系列)

    题意:有一个数组a和一个数组k,数组a一直保持一个性质:a[i + 1] >= a[i] + k[i].有两种操作:1,给某个元素加上x,但是加上之后要保持数组a的性质.比如a[i]加上x之后, ...

  5. Codeforces Round #546 (Div. 2) E - Nastya Hasn't Written a Legend

    这题是一个贼搞人的线段树 线段树维护的是 区间和a[i - j] 首先对于update的位置可以二分查找 其次update时候的lazy比较技巧 比如更新的是 l-r段,增加的是c 那么这段的值为: ...

  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. cf1136E. Nastya Hasn't Written a Legend(二分 线段树)

    题意 题目链接 Sol yy出了一个暴躁线段树的做法. 因为题目保证了 \(a_i + k_i <= a_{i+1}\) 那么我们每次修改时只需要考虑取max就行了. 显然从一个位置开始能影响到 ...

  8. 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- ...

  9. codeforces 1136E 线段树

    codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...

随机推荐

  1. RabbitMQ学习第一记:用java连接RabbitMQ

    1.什么是RabbitMQ MQ(Message Queue):消息队列,是服务端设计的一个可以存储大量消息的队列,并提供客户端操作队列的方法:生产队列(向队列中添加数据).消费队列(从队列中取数据) ...

  2. stelller插件与background-attachment配合使用,制作滚动页面

    stelller插件与background-attachment:fixed配合使用,制作滚动页面

  3. Estimation

    Estimation 给出一个长度为n序列\(\{a_i\}\),将其划分成连续的K段,对于其中一段\([l,r]\),设其中位数为m,定义其权值为\(\sum_{i=l}^r|m-a_i|\),求最 ...

  4. Java导出pdf文件数据

    提示:导出pdf文件,需要3个jar包iText-2.1.5.jar,iTextAsian.jar,iText-rtf-2.1.4.jar. public boolean outputPdfJhsy( ...

  5. thinkphp 标签库

    内置的模板引擎除了支持普通变量的输出之外,更强大的地方在于标签库功能. 标签库类似于Java的Struts中的JSP标签库,每一个标签库是一个独立的标签库文件,标签库中的每一个标签完成某个功能,采用X ...

  6. 17个方法防止dedeCMS织梦网站被黑挂木马

    dede织梦cms系统的程序存在漏洞,黑客攻击方法层出不穷,导致网站经常被黑,被百度安全中心等拦截,影响排名和流量,让站长非常头疼,下面总结一些防止dede织梦cms系统被攻击设置的方法,可有效的防止 ...

  7. VS2010-MFC(常用控件:树形控件Tree Control 下)

    转自:http://www.jizhuomi.com/software/203.html 前面一节讲了树形控件Tree Control的简介.通知消息以及相关数据结构,本节继续讲下半部分,包括树形控件 ...

  8. redis服务后台运行

    文章目录 进入redis的安装目录 查看目录结构 进入src目录,普通启动效果 编辑redis服务目录下的redis.conf 进入src目录,执行后台运行的命令 检查服务是否开启 进入redis的安 ...

  9. (一)通过JAVA连接SAP (sapjco3.jar在Windows和MacOS上的配置)

    (一)通过JAVA连接SAP调用接口 (sapjco3.jar在Windows和MacOS上的配置) 一.sapjoc3.jar获取 由于sap官网提供的链接需要合作公司提供账号密码,如果商用请索要正 ...

  10. USB电扇无刷电机改装

    现在USB电扇已经很常见了,网上随便可以低价买到.里面的电机分为有刷和无刷两种.我拆过的有刷USB电扇都非常劣质,里面的电机貌似是旧DVD机的拆机货:而无刷也有优劣之分,有的硅钢片非常少,铜线也细.这 ...