题目描述

给出一个长度为 $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. 交换机 路由器 OSI7层模型

    第1章 网络基础 1.1 网络的出现 解决计算机通讯的需求 实现计算机信息可以传递 1.2 主机之间实现通讯基本要求(三要素) ①. 需要在两台主机之间建立物理连接,物理连接的方式有网线 光纤线 wi ...

  2. 41F继电器座的解剖与妙用

    摘要:如果继电器不是焊在电路板上使用,就需要有个插座,这样方便接线,否则继电器的管脚是没法固定导线的.实际项目中使用了HF41F的继电器(宏发),在选择继电器座的时候,有一点感想,分享给大家.继电器是 ...

  3. [学习笔记]编译sensetime发表的Single View Stereo Matching(SVS)遇到的问题

    最近在研究用深度学习预测图像深度信息的方法,一开始用的是2017年CVPR上Godard大神的monodepth,代码在这里.这篇文章介绍了利用双目的consistency训练网络以对单张图像进行深度 ...

  4. [C++]值传递和引用传递

    概念 在定义函数时函数括号中的变量名成为形式参数,简称形参或虚拟参数: 在主调函数中调用一个函数时,该函数括号中的参数名称为实际参数,简称实参,实参可以是常量.变量或表达式. 注意: C语言中实参和形 ...

  5. GlusterFS分布式存储集群-2. 使用

    参考文档: Quick Start Guide:http://gluster.readthedocs.io/en/latest/Quick-Start-Guide/Quickstart/ Instal ...

  6. 高可用OpenStack(Queen版)集群-1. 集群环境

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

  7. ResNet——Deep Residual Learning for Image Recognition

    1. 摘要 更深的神经网络通常更难训练,作者提出了一个残差学习的框架,使得比过去深许多的的网络训连起来也很容易. 在 ImageNet 数据集上,作者设计的网络达到了 152 层,是 VGG-19 的 ...

  8. C++判断回文

    判断一个字符串是否为回文,如“goddog”. 代码: #include <iostream> #include <string> #include <stdio.h&g ...

  9. python的多路复用实现聊天群

    在我的<python高级编程和异步io编程>中我讲解了socket编程,这里贴一段用socket实现聊天室的功能的源码,因为最近工作比较忙,后期我会将这里的代码细节分析出来,目前先把代码贴 ...

  10. HDFS handler

    http://docs.oracle.com/goldengate/bd1221/gg-bd/GADBD/GUID-85A82B2E-CD51-463A-8674-3D686C3C0EC0.htm#G ...