题目描述

给出一个长度为 $n$ 的序列,对于 $1\sim n$ 的每一个数 $i$ ,求这个序列所有长度为 $i$ 的子区间的最大值之和,输出每一个 $i$ 的答案模 $998244353$ 后异或起来的结果即可。

$n\le 10^6$ 。


题解

单调栈+差分

考虑位置 $i$ 作为最大值的贡献:使用单调栈求出这个数左面第一个大于等于它的位置 $lp_i$ ,和它后面第一个大于它的位置 $rp_i$ 。

那么所有以它为最大值的区间都满足:左端点在 $[lp_i+1,i]$ 范围内,右端点在 $[i,rp_i-1]$ 范围内。

设 $p=\text{min}(i-lp_i,rp_i-i)$ ,$q=\text{max}(i-lp_i,rp_i-i)$ ,那么 $i$ 的贡献相当于:

给 $[1,p)$ 内的长度 $x$ 加上 $x·a_i$ ;
给 $[p,q)$ 内的长度 $x$ 加上 $p·a_i$ ;
给 $[q,p+q)$ 内的长度 $x$ 加上 $(p+q-x)·a_i$ 。

维护两个差分数组,它们 $i$ 位置的的前缀和分别表示:给 $i$ 位置加上 $该数$ 、给 $i$ 位置加上 $该数·i$ 。

这样区间加、减就相当于在差分数组上修改。

最后统计前缀和,求答案即可。

时间复杂度 $O(n)$

#include <cstdio>
#include <algorithm>
#define N 1000010
#define mod 998244353
using namespace std;
typedef long long ll;
int sta[N] , top , lp[N] , rp[N];
ll a[N] , s[N] , ss[N];
inline void add(ll &x , ll y) {x = (x + y) % mod;}
inline void del(ll &x , ll y) {x = ((x - y) % mod + mod) % mod;}
int main()
{
int n , i , p , q;
ll ans = 0;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%lld" , &a[i]);
while(top && a[i] > a[sta[top]]) top -- ;
lp[i] = sta[top] , sta[++top] = i;
}
top = 0 , sta[0] = n + 1;
for(i = n ; i ; i -- )
{
while(top && a[i] >= a[sta[top]]) top -- ;
rp[i] = sta[top] , sta[++top] = i;
p = i - lp[i] , q = rp[i] - i;
if(p > q) swap(p , q);
add(ss[1] , a[i]) , del(ss[p] , a[i]);
add(s[p] , p * a[i]) , del(s[q] , p * a[i]);
del(ss[q] , a[i]) , add(ss[p + q] , a[i]) , add(s[q] , (p + q) * a[i]) , del(s[p + q] , (p + q) * a[i]);
}
for(i = 1 ; i <= n ; i ++ ) add(s[i] , s[i - 1]) , add(ss[i] , ss[i - 1]) , ans ^= (s[i] + ss[i] * i) % mod;
printf("%lld\n" , ans);
return 0;
}

【uoj#213】[UNR #1]争夺圣杯 单调栈+差分的更多相关文章

  1. [UOJ213][UNR #1]争夺圣杯

    uoj description 一个长为\(n\)的序列,给定一个参数\(m\),求所有长度为\(m\)的区间的最大值之和. 对于所有的\(m\in[1,n]\)你都需要分别求出答案然后异或起来. \ ...

  2. uoj#213. 【UNR #1】争夺圣杯(单调栈)

    传送门 我们枚举每一个元素,用单调栈做两遍计算出它左边第一个大于它的位置\(l[i]\)和右边第一个大于它的位置\(r[i]\),那么一个区间以它为最大值就意味着这个区间的左端点在\([l[i]+1, ...

  3. uoj#213. 【UNR #1】争夺圣杯

    http://uoj.ac/problem/209 单调栈求出每个位置x左边第一个大于它的位置L[x]和右第一个不小于它的位置R[x],于是矩形L[x]<=l<=x<=r<=R ...

  4. UOJ#213——【UNR #1】争夺圣杯

    1.题意:给一个序列,枚举长度x,然后在这个序列中所有长度为x的区间,我们求出这些区间的最大值之和并取模,最后将所有的异或起来就好啦 2.分析:听说好多人写的 ,特来写一发 的算法骗访问量 话说这个东 ...

  5. 【UOJ UNR #1】争夺圣杯

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 考虑直接对每个数字,统计它会产生的贡献. 单调栈求出每个数字左边第一个大等于他的数,右边第一个大于他的 (注意只能有一边取等) 假设左 ...

  6. uoj213 【UNR #1】争夺圣杯

    题目 设\(f_i\)表示所有长度为\(i\)的区间的最大值的和,求\(\bigoplus \sum_{i=1}^nf_i\) 不难发现随机数据非常好做 由于一个随机序列的前缀最大值期望只会变化\(\ ...

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

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

  8. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  9. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

随机推荐

  1. SQL Server Management Studio 评估期已过

    SQL2008破解: (1)将SQL安装光盘(或者ISO)放进去运行,进入安装界面. (2)选择“维护”中的“版本升级”,如图: (3)按照版本升级的向导,先输入产品密钥,也就是正式企业版的序列号: ...

  2. 闭包初体验 -《JavaScript面向对象编程指南》

    下面是我对闭包的理解:(把他们整理出来,整理的过程也是在梳理) 参考<JavaScript面向对象编程指南> 1.首先,在理解闭包之前: 我们首先应该清楚下作用域和作用域链 作用域:每个函 ...

  3. cocos creator踩坑日记

    踩坑一 问题:项目在构建成Web Mobile后运行在浏览器和微信中,点击页面任何地方都会导致自动全屏 解决:在构建之后的main.js中,去掉 cc.view.enableAutoFullScree ...

  4. STM8S——watchdog(IWDG)

    IWDG工作原理: 1.当键值寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就会被启动,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号. 2.使用IWD ...

  5. 图片缩放插件GestureImageView——Android 常用插件推荐(一)

    Android 开发过程中,交互效果是一个非常繁琐的过程,甚至比Web开发过程中JS特效更加复杂.通过多年的发展,常用的交互方式已经发展相当成熟,而且有很多非常好的插件.为了避免重复造轮子,一些常用的 ...

  6. [PLC]ST语言一:LD_LDI_AND_ANI_OR_ORI

    一:LD_LDI_AND_ANI_OR_ORI基本指令 说明:简单的顺控指令不做其他说明. 控制要求:无 编程梯形图: 结构化编程ST语言: M400:=(M0 OR M1) AND M2; M401 ...

  7. Linux中的mysql指令

    如何启动/停止/重启MySQL一.启动方式1.使用 service 启动:service mysqld start2.使用 mysqld 脚本启动:/etc/inint.d/mysqld start3 ...

  8. Unity扩展编辑器四

    Inspector视图中的get/set使用 get  set使用起来很方便,但编辑时,在Inspector视图中问题就来了,因为get/set的属性即使是public了,但是在Inspector视图 ...

  9. grok正则

    USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME} INT (?:[+-]?(?:[0-9]+)) BASE10NUM (?<![0-9.+-])(?>[+ ...

  10. .NET处理Json的几种方式

    序列化里的xml,soap,binary在上一篇文章里面已经说过了,这篇主要说json. json是目前非常流行的一种序列化数据的方式,很多api都采用的是json,结构简洁,容易理解,适用性强,逐渐 ...