通过打表证明发现答案就是把序列划分成若干段,每段的b都是这一段a的平均数。50分做法比较显然,就是单调栈维护,每次将新元素当成一个区间插入末尾,若b值不满足单调不降,则将这个区间与单调栈前一个区间合并。

由于题目要求每次只修改一个数,所以可以前后缀拼起来,单调栈要改变,然后发现这个显然满足二分的性质,二分完位置左端点后再二分右端点,写一个可持久化单调栈维护一下就可以了。

还有一种主席树做法,后序可能会补上。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pii;
typedef long long ll;
const int N=1e5+,mod=;
int n,m,sum,tp1,tp2,a[N],f[N],g[N],inv[N],ans[N],st1[N],st2[N];
ll s[N];
vector<int>G[N];
vector<pii>q[N];
bool cmp(int l,int r,int L,int R,int x,int y)
{return (s[r]-s[l-]+x)*(R-L+)>(s[R]-s[L-]+y)*(r-l+);}
int calc(int l,int r,int x)
{return mod-(s[r]-s[l-]+x)%mod*((s[r]-s[l-]+x)%mod)%mod*inv[r-l+]%mod;}
int main()
{
scanf("%d%d",&n,&m);
inv[]=;for(int i=;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=;i<=n;i++)scanf("%d",&a[i]),s[i]=s[i-]+a[i],sum=(sum+1ll*a[i]*a[i])%mod;
q[].push_back(pii(a[],)),ans[]=sum;
for(int i=,x,y;i<=m;i++)
scanf("%d%d",&x,&y),q[x].push_back(pii(y,i)),ans[i]=(sum+1ll*(mod-a[x])*a[x]+1ll*y*y)%mod;
for(int i=;i<=n;i++)
{
while(tp1&&cmp(st1[tp1-]+,st1[tp1],st1[tp1]+,i,,))G[i].push_back(st1[tp1--]);
st1[++tp1]=i,f[tp1]=(f[tp1-]+calc(st1[tp1-]+,i,))%mod;
}
st2[]=n+;
for(int i=n;i;i--)
{
tp1--;
reverse(G[i].begin(),G[i].end());
for(int j=;j<G[i].size();j++)
st1[++tp1]=G[i][j],f[tp1]=(f[tp1-]+calc(st1[tp1-]+,G[i][j],))%mod;
if(i<n)
{
while(tp2&&cmp(i+,st2[tp2]-,st2[tp2],st2[tp2-]-,,))tp2--;
st2[++tp2]=i+,g[tp2]=(g[tp2-]+calc(i+,st2[tp2-]-,))%mod;
}
for(int j=;j<q[i].size();j++)
{
int x=q[i][j].first,y=q[i][j].second,l=,r=tp1,mid,now=,d=x-a[i];
while(l<=r)
{
mid=l+r>>;
if(cmp(st1[mid-]+,st1[mid],st1[mid]+,i,,d))r=mid-;
else l=mid+,now=mid;
}
if(!tp2||!cmp(st1[now]+,i,i+,st2[tp2-]-,d,))
ans[y]=(1ll*ans[y]+calc(st1[now]+,i,d)+f[now]+g[tp2])%mod;
else{
l=,r=tp2-;
int ret=,cur=;
while(l<=r)
{
mid=l+r>>;
int L=,R=now,Mid,pos=;
while(L<=R)
{
Mid=L+R>>;
if(cmp(st1[Mid-]+,st1[Mid],st1[Mid]+,st2[mid]-,,d))R=Mid-;
else L=Mid+,pos=Mid;
}
if(mid&&cmp(st1[pos]+,st2[mid]-,st2[mid],st2[mid-]-,d,))r=mid-;
else l=mid+,ret=mid,cur=pos;
}
ans[y]=(1ll*ans[y]+calc(st1[cur]+,st2[ret]-,d)+f[cur]+g[ret])%mod;
}
}
}
for(int i=;i<=m;i++)printf("%d\n",ans[i]);
}

单调栈做法

[HNOI2019]序列(单调栈+二分)的更多相关文章

  1. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  2. bzoj 4709 [Jsoi2011]柠檬——单调栈二分处理决策单调性

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 题解:https://blog.csdn.net/neither_nor/articl ...

  3. BZOJ1012最大数 [JSOI2008] 单调栈+二分

    正解:单调栈+二分查找(or,线段树? 解题报告: 拿的洛谷的链接quq 今天尝试学习了下单调栈,然后就看到有个博客安利了这个经典例题?于是就去做了,感觉还是帮助了理解趴quqqqqq 这题,首先,一 ...

  4. 51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线

     区间计数   基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80   两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{ ...

  5. 【bzoj4237】稻草人 分治+单调栈+二分

    题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...

  6. 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)

    洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...

  7. 【洛谷5294】[HNOI2019] 序列(主席树维护单调栈+二分)

    点此看题面 大致题意: 给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小 ...

  8. 【洛谷P1823】音乐会的等待 单调栈+二分

    题目大意:给定一个长度为 N 的序列,定义两个数 \(a[i],a[j]\) 相互看得见,意味着 \(\forall k\in [i+1,j-1],a[k]\le a[i],a[k]\le a[j]\ ...

  9. BZOJ 2122 [分块+单调栈+二分](有详解)

    题面 传送门 给定序列d和lim.假设有一个初始价值\(x_0\),则经历第i天后价值变为\(min(x_0+d[i],lim[i])\),记\(f(i,j,x_0)\)表示以初始代价x0依次经过第i ...

随机推荐

  1. JS照片轮换

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Python win32api.keybd_event模拟键盘输入

    win32api.keybd_event 该函数原型:keybd_event(bVk, bScan, dwFlags, dwExtraInfo) 第一个参数:虚拟键码(键盘键码对照表见附录): 第二个 ...

  3. 吴裕雄--天生自然 JAVASCRIPT开发学习

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 学习spring的第一天

    1.首先在maven repository中找到Spring Context依赖添加进模块 2.配置xml,resources右键new→xml configuration file→Spring C ...

  5. chown virtualbox

    virtualbox安装 root@cbill-VirtualBox:/# chown --help用法:chown [选项]... [所有者][:[组]] 文件... 或:chown [选项]... ...

  6. Ubuntu13.04闪屏的问题

    我的电脑Y460,双显切换,win7+ubuntu双系统,就是这个坑爹的双显切换,导致安装ubuntu13.04后屏老闪,网上查阅资料得知是显卡问题,一种是说显卡驱动问题,一种是说双显卡问题,双显卡问 ...

  7. jquery---利用jquery插件生成二维码

    <script type="text/javascript" src="<?php echo RESOURCE_SITE_URL;?>/js/jquer ...

  8. centos 7 内存压测测试--memtester工具

    1.下载memteste工具 官方:http://pyropus.ca/software/memtester/ wget http://pyropus.ca/software/memtester/ol ...

  9. pymysql常见报错

    错误一: AttributeError: module 'pymysql' has no attribute 'connect' 有道翻译 AttributeError:模块'pymysql'没有属性 ...

  10. ZJNU 2345 - 小Y的方格纸

    明显,总共有n*m格,已经涂了k格 所以剩下n*m-k格 如果n*m-k<=k,即k已经占用了大于等于一半的格子,显然答案为0 否则 剩下的格子中取k+1,k+2...n*m-k格均可 取组合数 ...