Description

给定一个长度为 \(n\le 3*10^6\) 的序列

\(q\le 10^7\) 次询问每次求区间 \([l,r]\) 的所有子区间的最小值的和

询问随机

Solution

考虑求出区间的最小值, 设在位置 \(p\)

考虑 \([l, p)\) 和 \((p, r]\) 的答案

\([l, p) = [l, n] - [p, n] - (左端点在[l, p) 右端点在[p, n] 的)\)

因为 \([l, p)\) 都比 \(p\) 小

所以该部分为 \((p-l) * 左端点在p的答案\)

区间最小值可以用rmq求

正常的O(n)-O(1) rmq需要转成树, 然后变成 \(\pm 1\) 的, 然后分块块内还要预处理, 常数很大

注意到这题询问随机, 询问到块内的几率很小, 所以可以把块内的处理改成暴力

块边缘维护前后缀min即可

Code

#include <bits/stdc++.h>
using namespace std;
#define ri rd<int>
#define rep(i, a, b) for (int i = (a), _ = (b); i <= _; ++i)
#define per(i, a, b) for (int i = (a), _ = (b); i >= _; --i)
#define For(i, a, b) for (int i = (a), _ = (b); i < _; ++i)
const int maxN = 3e6 + 7;
const int INF = 1e9 + 7;
typedef long long LL;
const LL O = 1e9 + 7; template<class T> T rd() {
bool f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
T x = 0; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return f ? x : -x;
} int n, m;
int a[maxN]; namespace IO {
int A, B, C, P;
LL lastAns; inline int rnd() {
return A = (A * B + (C ^ (int)(lastAns & 0x7fffffffLL)) % P) % P;
} void init() {
A = ri(), B = ri(), C = ri(), P = ri();
lastAns = 0;
}
} namespace RMQ {
const int maxL = 3e5 + 7;
const int B = 12;
struct Node {
int l, r, v;
int pre[12], suf[12];
}a[maxL]; int st[maxL][20];
int ln[maxL];
int bl[maxN]; void gmin(int &x, int y) {
if (::a[y] < ::a[x]) x = y;
} int ggmin(int x, int y) {
return ::a[x] < ::a[y] ? x : y;
} void init() {
rep (i, 1, n) {
int &t = bl[i] = i / B;
int &v = st[t][0];
if (a[t].l == 0) {
a[t].l = i;
v = i;
}
a[t].r = i;
gmin(v, i);
} int T = bl[n];
rep (j, 0, T) {
Node &t = a[j];
int l = t.l, r = t.r;
t.pre[0] = l;
rep (i, l+1, r) t.pre[i-l] = ggmin(t.pre[i-l-1], i);
t.suf[0] = r;
per (i, r-1, l) t.suf[r-i] = ggmin(t.suf[r-i-1], i);
} rep (i, 2, T) ln[i] = ln[i >> 1] + 1;
per (i, T, 0) {
rep (j, 1, ln[T-i+1])
st[i][j] = ggmin(st[i][j-1], st[i+(1<<(j-1))][j-1]);
}
} int eval(int l, int r) {
int len = ln[r-l+1];
return ggmin(st[l][len], st[r-(1<<len)+1][len]);
} int get(int l, int r) {
int res = l;
if (bl[l] == bl[r]) {
rep (i, l, r) gmin(res, i);
return res;
}
int u = bl[l], v = bl[r];
gmin(res, a[u].suf[a[u].r - l]);
gmin(res, a[v].pre[r - a[v].l]);
if (u+1 < v) gmin(res, eval(u+1, v-1));
return res;
}
} namespace Solve {
LL pre[maxN], suf[maxN]; void init() {
static int stack[maxN], Top;
stack[Top = 0] = 0;
LL res = 0;
rep (i, 1, n) {
for (; Top && a[stack[Top]] >= a[i]; --Top)
res -= 1LL * a[stack[Top]] * (stack[Top] - stack[Top-1]);
stack[++Top] = i;
res += 1LL * a[i] * (stack[Top] - stack[Top-1]);
pre[i] = res;
}
res = 0;
per (i, n, 1) {
for (; Top && a[stack[Top]] >= a[i]; --Top)
res -= 1LL * a[stack[Top]] * (stack[Top-1] - stack[Top]);
stack[++Top] = i;
res += 1LL * a[i] * (stack[Top-1] - stack[Top]);
suf[i] = res;
}
rep (i, 1, n) pre[i] += pre[i-1];
per (i, n, 1) suf[i] += suf[i+1];
} LL getr(int l, int r) {
return suf[l] - suf[r] - 1LL * (r-l) * (suf[r] - suf[r+1]);
} LL getl(int l, int r) {
return pre[r] - pre[l] - 1LL * (r-l) * (pre[l] - pre[l-1]);
}
} LL get(int l, int r) {
int p = RMQ::get(l, r);
LL res = 1LL * (p-l+1) * (r-p+1) * a[p];
if (l < p) res += Solve::getr(l, p);
if (p < r) res += Solve::getl(p, r);
return res;
} int main() {
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin);
#endif n = ri(), m = ri();
rep (i, 1, n) a[i] = ri();
IO::init();
RMQ::init();
Solve::init(); LL res = 0;
rep (i, 1, m) {
int l = IO::rnd() % n + 1, r = IO::rnd() % n + 1;
if (l > r) std::swap(l, r);
LL &tp = IO::lastAns = get(l, r);
res += tp % O;
}
printf("%lld\n", (res % O + O) % O); return 0;
}

LOJ 6057 - [HNOI2016]序列 加强版再加强版的更多相关文章

  1. P6604 [HNOI2016]序列 加强版

    *I. P6604 [HNOI2016]序列 加强版 摘自学习笔记 简单树论 笛卡尔树部分例题 I. 和 P6503 比较类似.我们设 \(f_i\) 表示全局以 \(i\) 结尾的子区间的最小值之和 ...

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

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

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

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

  4. [HNOI2016]序列 CDQ+DP

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

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

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

  6. 【LG3246】[HNOI2016]序列

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

  7. 4540: [Hnoi2016]序列

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

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

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

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

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

随机推荐

  1. 【多线程】 Task

    [多线程] Task 一. 常用方法: 1. ContinueWith : 当前 Task 完成后, 执行传入的 Task 2. Delay : 创建一个等待的 Task,只有在调用 Wait 方法时 ...

  2. 从循环里面用QPixmap new对象很耗时联想到的

    1.在循环里面用QPixmap new图片对象延迟很高,这个是通过打时间日志得出的,深层原因还不清楚: 2.自制的图片浏览器在初始化的时候会初始化自己的一个图片列表,所以要用到上面的描述.所有图片的初 ...

  3. 使用CodeBlocks为你的程序添加程序文件图标和启动读入图标

    其实也非常简单,自己这两天用win32api做了一个小程序,可是发现图标却是dos的,太难看了,于是就想起以前学win32汇编时候用到的工具,ResEd,已经被我汉化了一些,估计有新的版本发布吧,但是 ...

  4. (原创)不过如此的 DFS 深度优先遍历

    DFS 深度优先遍历 DFS算法用于遍历图结构,旨在遍历每一个结点,顾名思义,这种方法把遍历的重点放在深度上,什么意思呢?就是在访问过的结点做标记的前提下,一条路走到天黑,我们都知道当每一个结点都有很 ...

  5. Python 学习笔记之—— PIL 库

    PIL,全称 Python Imaging Library,是 Python 平台一个功能非常强大而且简单易用的图像处理库.但是,由于 PIL 仅支持到Python 2.7,加上年久失修,于是一群志愿 ...

  6. android问题笔记集

    开发工具:android studio2.2 调试:手机直连调试,版本(android6) 问题1: Error:Unable to start the daemon process. This pr ...

  7. Python图像全屏显示

    需要在嵌入式设备上全屏显示图像,使用pil显示图像时,只能通过系统的图像浏览器显示.所以使用Python自带的tkinter import Tkinter as tk   这句在Python3中已经改 ...

  8. POJ 2161 Chandelier(动态规划)

    Description Lamps-O-Matic company assembles very large chandeliers. A chandelier consists of multipl ...

  9. c语言实现带LRU机制的哈希表

    #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h&g ...

  10. ExtJS新手学习中常见问题

    1.常常出现运行之后不出现应该出现的效果. 这种情况一般是引用ExtJS路径不正确,要确保路径正确. 示例: <!DOCTYPE html> <html lang="en& ...