前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CF878E Numbers on the blackboard

CF878E Numbers on the blackboard

作者头像
yzxoi
发布2022-09-19 13:50:46
6970
发布2022-09-19 13:50:46
举报
文章被收录于专栏:OI

CF878E Numbers on the blackboard

题目链接:CF878E

给出 n 个数字,每次询问一个区间 [l,r],对这个区间内部的点进行操作。 每次操作可以合并相邻两个数 x,y 其中 x before y,将它们变成 x+2y 对于每次询问输出当最后只剩下一个数字时,这个数字的最大值。 询问互相独立,答案对 10^9+7 取模。

1\leq n,q\leq 10^5,-10^9\leq a_i\leq10^9

Sol

一开始没看到 x before y 和指导胡扯了好久

显然一定是从左到右,如果当前数为非负数,一定将该数与上一块进行合并;如果当前数为非负数,一定是给它单独新开一个块。

如果合并后导致原来一个贡献为负的块贡献变为正了,则继续向前合并,显然这样贡献最大。

最后一定是从后往前依次将每个块合并。

显然最后每个数的贡献一定是 2 的幂,可以提前预处理。

然后把询问离线下来,按照 r 端点排个序然后每次考虑插点合并块即可。

然后左端点所在的块会拆开,但是显然这拆开的部分一定不会与后面合并(这样肯定不优)。

最后有个小细节,合并如何判断正负(在取模之后)?显然如果一个块内的权值之和已经超过了 10^{14} 则一定能把之前的所有块都合并了,于是只需要每个块单独的和先用 long long 存即可。

时间复杂度 \mathcal O(N\log N)

代码语言:javascript
复制
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define W while
#define I inline
#define RI register int
#define LL long long
#define Cn const
#define CI Cn int&
#define gc getchar
#define D isdigit(c=gc())
#define pc(c) putchar((c))
using namespace std;
namespace Debug{
    Tp I void _debug(Cn char* f,Ty t){cerr<<f<<'='<<t<<endl;}
    Ts I void _debug(Cn char* f,Ty x,Ar... y){W(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);}
    Tp ostream& operator<<(ostream& os,Cn vector<Ty>& V){os<<"[";for(Cn auto& vv:V) os<<vv<<",";os<<"]";return os;}
    #define gdb(...) _debug(#__VA_ARGS__,__VA_ARGS__)
}using namespace Debug;
namespace FastIO{
    Tp I void read(Ty& x){char c;int f=1;x=0;W(!D) f=c^'-'?1:-1;W(x=(x<<3)+(x<<1)+(c&15),D);x*=f;}
    Ts I void read(Ty& x,Ar&... y){read(x),read(y...);}
    Tp I void write(Ty x){x<0&&(pc('-'),x=-x,0),x<10?(pc(x+'0'),0):(write(x/10),pc(x%10+'0'),0);}
    Tp I void writeln(Cn Ty& x){write(x),pc('\n');}
}using namespace FastIO;
Cn int N=1e5+10,p=1e9+7,Inv2=500000004;
Cn LL inf=1e15;
int n,q,a[N],inv[N],pw[N],stk[N],top;
LL s[N],S[N],SS[N],Ans[N];
struct Que{int l,r,id;}Q[N];
vector<int> v[N];
#define pb push_back
int main(){
    RI i,t;for(read(n,q),pw[0]=inv[0]=1,i=1;i<=n;i++) read(a[i]),s[i]=(s[i-1]+1LL*(pw[i]=2LL*pw[i-1]%p)*a[i]%p)%p,inv[i]=1LL*inv[i-1]*Inv2%p;
    for(i=1;i<=q;i++) read(Q[i].l,Q[i].r),Q[i].id=i,v[Q[i].r].pb(i);
    for(i=1;i<=n;i++){
        stk[++top]=i,S[top]=a[i];
        W(top&&S[top]>0) (1LL<<stk[top]-stk[top-1])>(inf-S[top-1])/S[top]?S[top-1]=inf:S[top-1]+=(1<<stk[top]-stk[top-1])*S[top],top--;
        SS[top]=S[top]<inf?(SS[top-1]+S[top])%p:s[i];for(auto j:v[i]){
            stk[top+1]=Q[j].r+1,t=upper_bound(stk+1,stk+top+2,Q[j].l)-stk;
            Ans[Q[j].id]=((2LL*(SS[top]-SS[t-1]+p)%p+1LL*(s[stk[t]-1]-s[Q[j].l-1]+p)*inv[Q[j].l]%p)%p+p)%p;
        }
    }for(i=1;i<=q;i++) writeln(Ans[i]);
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CF878E Numbers on the blackboard
    • Sol
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档