题目描述

给出一个长度为 $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. javascript中的toString()方法

    javascript中的toString()方法,主要用于Array.Boolean.Date.Error.Function.Number等对象.下面是这些方法的一些解析和简单应用,做个纪律,以作备忘 ...

  2. Mkdir方法

    新建目录或文件夹. 语法 MkDir 路径 所需的_路径_参数是一个字符串表达式,标识的目录或文件夹创建. _路径_可以包含驱动器. 如果未指定驱动器, MkDir当前的驱动器上创建新目录或文件夹. ...

  3. Rxjava - 操作符,线程操作的简单使用

    目录 创建操作符 10种常用的操作符定义 下面做几个操作符的demo演示 create from repeat defer interval Scheduler 什么是Scheduler? 如何使用S ...

  4. 树莓派UPS-18650,添加时钟

    1.简介 UPS-18650 是一个专门为树莓派(以下简称 pi)所设计的 UPS 电源,采用两颗标准 的 18650 锂电池进行供电,支持外部电源插入检测,支持边充边放,既插上外部电源时, pi 由 ...

  5. **测试某系统切换成docker部署之后性能的下降情况**

    ###分析 * 对比:某系统/docker* A:某系统性能情况* B:dockers部署的性能情况* 求出A&B两者之间的差异* 确定性能指标(tps)* 测试报告里体现:tps的变化 ## ...

  6. 【LeetCode算法题库】Day1:TwoSums & Add Two Numbers & Longest Substring Without Repeating Characters

    [Q1] Given an array of integers, return indices of the two numbers such that they add up to a specif ...

  7. golang应用打包成docker镜像

    golang编译的应用是不需要依赖其他运行环境的,那么为什么还需要打包成docker镜像呢?当需要附带配置和日志等文件时可以更方便的移植和运行,下面介绍从dockerfile编译成镜像. 在项目根目录 ...

  8. kali获得windows的shell后乱码

    输入 chcp 65001

  9. nginx 在ubuntu上使用笔记(绑定域名)

    1. 重启nginx的两个语句: sudo service nginx restart sudo nginx -s reload 2. nginx配置文件路径: etc/nginx/ 尤其是 site ...

  10. to_char

    to_date(to_char(to_date(#{conds.currentTime,jdbcType=VARCHAR},'YYYY-MM-DD hh24:mi:ss'),'hh24:mi:ss') ...