Description

给定一个正整数序列 \(a_1,a_2,\cdots,a_n\),求

\[\sum_{i=1}^n\sum_{j=i}^n(j-i+1)\min(a_i,a_{i+1},\cdots,a_j)\max(a_i,a_{i+1},\cdots,a_j)
\]

Input

第 \(1\) 行,一个整数 \(n\);

第 \(2\dots n+1\) 行,每行一个整数表示序列 \(a\)。

Output

输出答案对 \(10^9\) 取模后的结果。

Sample Input

4
2
4
1
4

Sample Output

109

HINT

\(n \le 500000,1 \le a_i \le 10^8\)

Solution

CDQ分治,从右往左枚举 \([l,mid]\) 的每个点 \(i\),设 \([i,mid]\) 的最小值为 \(mn\),最大值为 \(mx\),同时在 \([mid+1,r]\) 中维护两个指针 \(a,b\),满足 \(\min[mid+1,a]\ge mn,\max[mid+1,b]\le mx\)。假设 \(a<b\),那么 \([mid+1,r]\) 就被分成了三块,我们分别考虑 \(j\) 在每个块内的答案:

  • 若 \(mid<j\le a\),

\[\begin{eqnarray}
ans&=&mn\cdot mx\sum_{j=mid+1}^{a}(j-i+1)\\
&=&\frac{(a+mid-2i+3)(a-mid)}{2}
\end{eqnarray}
\]

  • 若 \(a< j \le b\),

\[\begin{eqnarray}
ans&=&mx\cdot\sum_{j=a+1}^b(j-i+1)\min[a+1,j]\\
&=&mx\left(\sum_{j=a+1}^bj\cdot\min[a+1,j]-(i-1)\sum_{j=a+1}^b\min[a+1,j]\right)\\
&=&mx\left(\sum_{j=a+1}^bj\cdot\min[1,j]-(i-1)\sum_{j=a+1}^b\min[1,j]\right)
\end{eqnarray}
\]

  • 若 \(b< j\le r\),

\[\begin{eqnarray}
ans&=&\sum_{j=b+1}^r(j-i+1)\min[b+1,j]\max[b+1,j]\\
&=&\sum_{j=b+1}^rj\cdot\min[b+1,j]\max[b+1,j]-(i-1)\sum_{j=b+1}^r\min[b+1,j]\max[b+1,j]\\
&=&\sum_{j=b+1}^rj\cdot\min[1,j]\max[1,j]-(i-1)\sum_{j=b+1}^r\min[1,j]\max[1,j]
\end{eqnarray}
\]

其中 \(\sum_{j=a+1}^bj\cdot\min[1,j]\),\(\sum_{j=a+1}^b\min[1,j]\),\(\sum_{j=b+1}^rj\cdot\min[1,j]\max[1,j]\),\(\sum_{j=b+1}^r\min[1,j]\max[1,j]\) 可以预处理前缀和得到。

Code

#include <cstdio>
#include <algorithm> using std::max; using std::min;
const int N = 500005, mod = 1000000000;
int a[N], n, s1[N], s2[N], s3[N], s4[N], s5[N], s6[N], ans; int read() {
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
void solve(int l, int r) {
if (l == r) { ans = (ans + 1LL * a[l] * a[l]) % mod; return; }
int mid = (l + r) >> 1, mn = mod, mx = 0, x;
solve(l, mid), solve(mid + 1, r);
for (int i = mid + 1; i <= r; ++i) {
mn = min(mn, a[i]), mx = max(mx, a[i]);
s1[i] = (s1[i - 1] + 1LL * i * mn) % mod;
if ((s2[i] = s2[i - 1] + mn) >= mod) s2[i] -= mod;
s3[i] = (s3[i - 1] + 1LL * i * mx) % mod;
if ((s4[i] = s4[i - 1] + mx) >= mod) s4[i] -= mod;
s5[i] = (s5[i - 1] + 1LL * i * mn % mod * mx) % mod;
s6[i] = (s6[i - 1] + 1LL * mn * mx) % mod;
}
mn = mod, mx = 0;
for (int i = mid, j = mid, k = mid; i >= l; --i) {
mn = min(mn, a[i]), mx = max(mx, a[i]);
while (j < r && a[j] >= mn && a[j + 1] >= mn) ++j;
while (k < r && a[k] <= mx && a[k + 1] <= mx) ++k;
if ((x = min(j, k))) ans = (ans + 1LL * mn * mx % mod * (((x + mid - i - i + 3LL) * (x - mid) >> 1) % mod)) % mod;
if (j < k) ans = (ans + ((s1[k] - s1[j]) - 1LL * (i - 1) * (s2[k] - s2[j])) % mod * mx) % mod;
if (j > k) ans = (ans + ((s3[j] - s3[k]) - 1LL * (i - 1) * (s4[j] - s4[k])) % mod * mn) % mod;
if ((x = max(j, k)) < r) ans = (ans + s5[r] - s5[x] - 1LL * (i - 1) * (s6[r] - s6[x])) % mod;
}
}
int main() {
n = read();
for (int i = 1; i <= n; ++i) a[i] = read();
solve(1, n);
if (ans < 0) ans += mod;
printf("%d\n", ans);
return 0;
}

[BZOJ 3745] [COCI 2015] Norma的更多相关文章

  1. BZOJ 3881 COCI 2015 Divljak

    题面 Description Tom有n个字符串S1,S2...Sn,Jerry有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: "1 P",Jerr ...

  2. bzoj 3743 [ Coci 2015 ] Kamp —— 树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 一开始想到了树形DP,处理一下子树中的最小值,向上的最小值,以及子树中的最长路和向上的 ...

  3. [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机

    [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机 题意 给定平面上的 \(n\) 个整点 \((x_i,y_i)\), 一共有两个问题. 第一个问题是从原 ...

  4. [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会

    [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会 题意 给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\ ...

  5. [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)

    [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...

  6. [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛) 题面 我们知道,从区间\([L,R]\)(L和R为整数)中选取N个整数,总共有\((R-L+1)^N\)种方案.求最大公约数 ...

  7. BZOJ 3745: [Coci2015]Norma(分治)

    题意 给定一个正整数序列 \(a_1, a_2, \cdots, a_n\) ,求 \[ \sum_{i=1}^{n} \sum_{j=i}^{n} (j - i + 1) \min(a_i,a_{i ...

  8. bzoj 3745 [Coci2015]Norma——序列分治

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3745 如果分治,就能在本层仅算过 mid 的区间了. 可以从中间到左边地遍历左边,给右边两个 ...

  9. bzoj 3745: [Coci2015]Norma

    Description Solution 考虑分治: 我们要统计跨越 \(mid\) 的区间的贡献 分最大值和最小值所在位置进行讨论: 设左边枚举到了 \(i\),左边 \([i,mid]\) 的最大 ...

随机推荐

  1. 国外线下技术俱乐部建设(1) - Belgrade Python技术俱乐部2019-01-25活动感悟

    这是<国外线下技术俱乐部建设>系列文章之一.   虽然之前接触过Belgrade的.NET技术俱乐部,但是它最近活动要春节后了. 出于观摩别人是怎么搞线下社区的心态,还有自己也有在用Pyt ...

  2. SpringBoot的自动配置原理过程解析

    SpringBoot的最大好处就是实现了大部分的自动配置,使得开发者可以更多的关注于业务开发,避免繁琐的业务开发,但是SpringBoot如此好用的 自动注解过程着实让人忍不住的去了解一番,因为本文的 ...

  3. Jmeter设置代理,抓包之app请求

    步骤: 1. Jmeter选择测试计划,添加线程组,添加http请求,添加监听器-察看结果树 2. 添加http代理服务器,右键添加非测试元件-添加http代理服务器 3. 端口改为8889,目标控制 ...

  4. ubuntu 通过apt安装jdk

    需要先添加ppa sudo add-apt-repository ppa:webupd8team/java sudo apt-get update 安装jdk8 sudo apt-get instal ...

  5. [转] Linux Asynchronous I/O Explained

    Linux Asynchronous I/O Explained (Last updated: 13 Apr 2012) *************************************** ...

  6. php去掉字符串的最后一个字符

    php去掉字符串的最后一个字符 //例如 $str = "12,34,56,"; $newstr = substr($str,0,strlen($str)-1); //从第一位开始 ...

  7. Windows程序设计:格式化对话框的设计

    刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows API函数的. MessageBox函数是许多人刚开始学习Windows程序设计或者是 ...

  8. 英语口语练习系列-C14-常用片语

    句子 1. Some ads are extremely persuasive and we find we buy products we don't really need. 有一些广告非常有说服 ...

  9. 【English】20190326

     Throughput吞吐量[ˈθruˌpʊt]  data movement数据移动 [ˈdetə ˈmuvmənt]  How to improve the Throughput for data ...

  10. netstat Recv-Q和Send-Q

    通过netstat -anp可以查看机器的当前连接状态:   Active Internet connections (servers and established) Proto Recv-Q Se ...