*I. P6604 [HNOI2016]序列 加强版

摘自学习笔记 简单树论 笛卡尔树部分例题 I.

P6503 比较类似。我们设 \(f_i\) 表示全局以 \(i\) 结尾的子区间的最小值之和,令 \(p_i\) 为下标在 \(i\) 之前第一个比 \(a_i\) 小的位置,显然有 \(f_i=f_{p_i}+(i-p_i)a_i\):因为 \(a_i\) 对 \(p_i\) 以及 \(p_i\) 以前的最小值没有影响(即 \([1,p_i]\) 与 \([1,i]\),\([2,p_i]\) 与 \([2,i]\cdots\) \([p_i,p_i]\) 与 \([p_i,i]\) 的最小值相同),所以可以直接由 \(f_{p_i}\) 转移得来。而根据 \(p_i\) 的定义,后面 \(i-p_i\) 个子序列(即 \([p_i+1,i],[p_i+2,i]\cdots,[i,i]\))的最小值为 \(a_i\)。

注意到 \(p_i\) 实际相当于 \(i\) 在笛卡尔树上第一个向左走的父亲,求 \(p_i\) 的过程十分类似构建笛卡尔树:笛卡尔树上每个节点的祖先由左右两个单调栈构成

考虑对一个区间求答案:求出区间最小值的位置 \(p\),那么左端在 \(p\) 左边,右端在 \(p\) 右边的子区间最小值为 \(a_p\),故答案加上 \(a_p\times (p-l+1)\times (r-p+1)\)。此外,我们还需求出 \([l,p)\) 与 \((p,r]\) 的答案:考虑 \((p,r]\) 每个位置对答案的贡献都是 \(f_r-f_p\),因为 \([i,p]\) 与 \([i,r]\ (1\leq i\leq p)\) 的最小值相同。前缀和优化可以做到 \(\mathcal{O}(1)\) 回答每个询问。对于 \([l,p)\) 同理,我们只需预处理出 \(g_i\) 表示全局以 \(i\) 开头的子区间的最小值之和并类似处理即可。

复杂度瓶颈在于区间 RMQ,时间复杂度 \(\mathcal{O}(n\log n+q)\)。

const int N = 1e5 + 5;
const int K = 17; namespace gen {
ull s, a, b, c, las = 0;
ull rand() {return s ^= (a + b * las) % c;}
} int n, q, type, stc[N], *top = stc, a[N], lg[N], pre[N], suf[N];
ll mi[K][N], fp[N], gp[N], fs[N], gs[N]; ull res;
int cmp(int x, int y) {return a[x] < a[y] ? x : y;}
int RMQ(int l, int r) {int d = lg[r - l + 1]; return cmp(mi[d][l], mi[d][r - (1 << d) + 1]);} int main(){
cin >> n >> q >> type;
for(int i = 1; i <= n; i++) a[i] = read(), mi[0][i] = i;
for(int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
for(int i = 1; i <= lg[n]; i++)
for(int j = 1; j + (1 << i) - 1 <= n; j++)
mi[i][j] = cmp(mi[i - 1][j], mi[i - 1][j + (1 << i - 1)]);
for(int i = 1; i <= n; i++) {
while(*top && a[*top] >= a[i]) suf[*top--] = i; // 可以类比求笛卡尔树的过程: ls[i] = *top, 因此 suf[*top] = i;
pre[i] = *top, *++top = i; // 同理, rs[*top] = i, 所以 pre[i] = *top: 笛卡尔树上每个节点的祖先是由两个单调栈构成的!
}
for(int i = 1; i <= n; i++)
fp[i] = fp[pre[i]] + 1ll * a[i] * (i - pre[i]), gp[i] = gp[i - 1] + fp[i];
for(int i = n; i; i--)
fs[i] = fs[suf[i]] + 1ll * a[i] * (suf[i] - i), gs[i] = gs[i + 1] + fs[i];
if(type) gen :: s = read(), gen :: a = read(), gen :: b = read(), gen :: c = read();
for(int i = 1, l, r; i <= q; i++) {
if(type == 0) l = read(), r = read();
else {
l = gen :: rand() % n + 1;
r = gen :: rand() % n + 1;
if(l > r) swap(l, r);
}
ll p = RMQ(l, r), ans;
ans = a[p] * (r - p + 1) * (p - l + 1);
ans += gp[r] - gp[p] - fp[p] * (r - p);
ans += gs[l] - gs[p] - fs[p] * (p - l);
res ^= gen :: las = ans;
}
cout << res << endl;
return flush(), 0;
}

P6604 [HNOI2016]序列 加强版的更多相关文章

  1. LOJ 6057 - [HNOI2016]序列 加强版再加强版

    Description 给定一个长度为 \(n\le 3*10^6\) 的序列 \(q\le 10^7\) 次询问每次求区间 \([l,r]\) 的所有子区间的最小值的和 询问随机 Solution ...

  2. BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]

    4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...

  3. 【LG3246】[HNOI2016]序列

    [LG3246][HNOI2016]序列 题面 洛谷 题解 60pts 对于每个位置\(i\),单调栈维护它往左第一个小于等于它的位置\(lp_i\)以及往右第一个小于它的位置\(rp_i\). 那么 ...

  4. 4540: [Hnoi2016]序列

    4540: [Hnoi2016]序列 https://www.lydsy.com/JudgeOnline/problem.php?id=4540 分析: 莫队+RMQ+单调栈. 考虑加入一个点后,区间 ...

  5. [BZOJ4540][HNOI2016]序列 莫队

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...

  6. BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*

    BZOJ4540 Hnoi2016 序列 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- ...

  7. 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈

    [BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...

  8. [Bzoj4540][Hnoi2016] 序列(莫队 + ST表 + 单调队列)

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1567  Solved: 718[Submit][Status] ...

  9. [HNOI2016]序列 CDQ+DP

    [HNOI2016]序列 CDQ 链接 loj 思路 一个点最小变为l,最大变为r,不变的时候为v 那么j能在i前面就要满足. \(j<i\) \(r[j]<=v[i]\) \(v[j]& ...

随机推荐

  1. FastAPI 学习之路(四十六)WebSockets(二)

    上一篇文章,我们分享了WebSockets一些入门的,我们这节课,在原来的基础上,对于讲解的进行一个演示.我们最后分享了依赖token等.首先我们对上次的代码进行调整. 我们之前分享FastAPI 学 ...

  2. Less-(26~28) preg_replace3

    Less-26: 核心语句:  各种回显均存在. 本题相比Less-25,多屏蔽了很多符号: 首先是各种注释符 --+,#,/**/  . /[]/表示字符集合:任何出现在里面的字符均会被替换. 屏蔽 ...

  3. Abp VNext分表分库,拒绝手动,我们要happy coding

    Abp VNext 分表分库 ShardingCore ShardingCore 易用.简单.高性能.普适性,是一款扩展针对efcore生态下的分表分库的扩展解决方案,支持efcore2+的所有版本, ...

  4. [BZOI2014]大融合——————线段树进阶

    竟然改了不到一小时就改出来了, 可喜可贺 Description Solution 一开始想的是边两侧简单路径之和的乘积,之后发现这是个树形结构,简单路径数就是节点数. 之后的难点就变成了如何求线段树 ...

  5. Python之@property详解及底层实现介绍

    转自:https://blog.csdn.net/weixin_42681866/article/details/83376484 前文 Python内置有三大装饰器:@staticmethod(静态 ...

  6. 还在用canvas画格子吗?文字烟花效果更不错噢

    大家好,我是小丞同学,一名前端爱好者 欢迎访问博主的个人网站:一口奶盖 "在人间贩卖声音 等凑够满天星辰 放烟花给你看" 上次的烟花有些许平淡,这次来放大招了,让你的名字在天空绽放 ...

  7. 文件上传漏洞Bypass总结

    文件上传漏洞Bypass总结 前端JS验证文件类型: 上传后缀jpg,抓包改为php后缀 ======================================================= ...

  8. poj 2960 S-Nim (SG)

    题意: K个数,s1...sk. m个状态,对于某一个状态,有L堆石子,每人每次取的石子个数只能是s1...sk的一个,且只能在一堆中取. 输出m个状态是先手胜还是先手败,先手胜输出W,否则输出L. ...

  9. 盘点 GitHub 年度盛会|附视频

    「Universe 2021」是 GitHub 于今年举办的开发者盛会,本次 Universe 2021 大会采用线上直播模式,为期两天已于上周落下帷幕. 这是 GitHub 举办的一年一度开发者盛会 ...

  10. supervisor安装

    supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作supervisor的子进程来启动,所以我们只需要将要管理进程的可执行文件的路径添加到supervisor的配置文件中 ...