题目

设\(f_i\)表示所有长度为\(i\)的区间的最大值的和,求\(\bigoplus \sum_{i=1}^nf_i\)

不难发现随机数据非常好做

由于一个随机序列的前缀最大值期望只会变化\(\log\)次,所以完全可以从这个条件上入手

考虑维护一个合并式单调栈,每次插入一个数之后,单调栈中存在的都是当前这个前缀所有的后缀最大值,我们直接暴力扫一遍这些后缀最大值,于是有一些针对\(f\)数组的区间加,我们直接差分维护就好了

这样在数据随机意义下是\(O(n\log n)\)的,一发跑过了除了\(\rm hack\)数据以外的所有数据也是非常惊人

考虑正解,使用单调栈找到一个位置\(i\)左边第一个小于等于他的\(j\),和右边第一个大于他的\(k\),显然在左端点在\([j,i]\)内,右端点在\([i,k)\)的区间的最大值都是\(a_i\),于是直接讨论一下\(a_i\)对这些长度区间的贡献就好了

设\(a=\min(i-j+1,k-i),b=\max(i-j+1,k-i)\)

对于长度为\([1,a]\)的区间,贡献是\(x\times a_i\)

对于长度为\([a+1,b]\)的区间,贡献是\(b\times a_i\)

对于长度为\([b+1,a+b-1]\)的区间,贡献为\((b-x)\times a_i=b\times a_i-x\times a_i\)

维护两个差分数组,一个用于维护这个位置实际上增加了多少,一个用于维护这个位置增加了多少倍的\(x\)

随便就做完了,复杂度是\(O(n)\)的

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353;
const int maxn=1e6+5;
int a[maxn],pre[maxn],mn[maxn],t[maxn],st[maxn],c[maxn];
int n,top;LL ans;
inline void calc(int pos) {
int a=t[top]-mn[top]+1,b=pos-t[top]+1;
if(a>b) std::swap(a,b);
int v=st[top]%mod;
if(a<b) {
pre[a+1]=(pre[a+1]+1ll*a*v%mod)%mod;
pre[b+1]=(pre[b+1]-1ll*a*v%mod+mod)%mod;
}
c[1]=(c[1]+v)%mod,c[a+1]=(c[a+1]-v+mod)%mod;
if(b<a+b-1) {
c[b+1]=(c[b+1]-v+mod)%mod,c[a+b]=(c[a+b]+v)%mod;
pre[b+1]=(pre[b+1]+1ll*(a+b)*v%mod)%mod;
pre[a+b]=(pre[a+b]-1ll*(a+b)*v%mod+mod)%mod;
}
}
int main() {
n=read();for(re int i=1;i<=n;++i) a[i]=read();top=0;
for(re int i=1;i<=n;i++) {
int now=i;
while(top&&a[i]>=st[top]) calc(i-1),now=mn[top],top--;
mn[++top]=now,t[top]=i,st[top]=a[i];
}
while(top) calc(n),top--;
for(re int i=1;i<=n;i++) pre[i]=(pre[i-1]+pre[i])%mod;
for(re int i=1;i<=n;i++) c[i]=(c[i-1]+c[i])%mod;
for(re int i=1;i<=n;i++)
pre[i]=(pre[i]+1ll*c[i]*i%mod)%mod,ans^=pre[i];
printf("%lld\n",ans);
}

最新文章

  1. Mac上idea快捷键
  2. 如何解决Response.Redirect方法传递汉字丢失或乱码问题?
  3. SAFS Distilled --- 9 April 2015 to 16 April 2015
  4. [转]理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站)
  5. 转载 C#使用Salt + Hash来为密码加密
  6. Hacker(19)----检测Windows系统漏洞
  7. 【转】树莓派学习笔记——I2C Tools 学习笔记
  8. 喜欢的女生快被别人抢走了,我敢怎么抢? - V2EX
  9. Callable,Runnable比较及用法
  10. vsftpd配置---------------------之chroot_local_user和chroot_list_enable含义
  11. Intersection(poj)
  12. HDU 3177 Crixalis&amp;#39;s Equipment(贪婪)
  13. Selenium八种基本定位方式---基于python
  14. 关于stm32的数据类型
  15. vue基于组件实现简单的todolist
  16. tmux终端工具的简单使用
  17. linux 平均负载 load average 的含义【转】
  18. C语言迷题:有符号数与无符号数的问题(转)
  19. 434. Number of Segments in a String
  20. W,b的初始化和几种激活函数

热门文章

  1. (转)rand函数和srand函数
  2. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
  3. java 原生 HttpClient
  4. jquery中的ajax方法参数的用法和他的含义
  5. img路径错误时,用户友好图片
  6. Linux环境变量永久设置方法(zsh)
  7. iptables默认规则
  8. opencv——常见的操作
  9. python-selenium -- 弹出框处理
  10. js 实用封装 点击按钮复制到剪贴板