要命的题目。

写法:分类讨论进行计算。

枚举过每一个\(mid\)的所有区间。对于左端点\(i∈[l, mid - 1]\),向左推并计算\([l,mid]\)范围内的最大\(/\)最小值。

然后右端点\(p\)分三种类型考虑。

  • \(p∈[mid + 1, p1 - 1]\),其中\(p1\)是第一次出现比\(maxw\)大或者比\(minw\)小的数的位置。

  • \(p∈[p1, p2 - 1]\),其中\(p2\)是第二次出现比\(maxw\)大或者比\(minw\)小的数的位置。

  • \(p∈[p2, r]\),\(r\)是当前枚举区间的右端点。

其中情况一高斯求和,情况二和情况三可以化为前缀最大最小值之和\(/\)积带几个系数的形式\(O(N)\)维护。

要命原因:取膜。

两年\(OI\)一场空,_______。

#include <bits/stdc++.h>
using namespace std; typedef long long LL;
const int N = 500000 + 5;
const LL Mod = 1000000000;
#define min(x,y) (x < y ? x : y)
#define max(x,y) (x > y ? x : y)
#define mul(x,y) ((1ll * (x % Mod) * (y % Mod)) % Mod)
#define add(x,y) ((0ll + (x % Mod) + (y % Mod)) % Mod) int n, arr[N]; LL ans; int _maxw[N], _minw[N]; LL mn1[N], mn2[N], mx1[N], mx2[N], mnmx1[N], mnmx2[N]; int get_maxp (int w, int l, int r) {
if (_maxw[r] <= w) return r + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (_maxw[mid] > w) {
r = mid;
} else {
l = mid + 1;
}
}
return r;
} int get_minp (int w, int l, int r) {
if (_minw[r] >= w) return r + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (_minw[mid] < w) {
r = mid;
} else {
l = mid + 1;
}
}
return r;
} void cdq (int l, int r) {
if (l == r) {
ans = add (ans, mul (arr[l], arr[r]));
return;
}
int mid = (l + r) >> 1;
cdq (l, mid + 0);
cdq (mid + 1, r);
int maxw = arr[mid], minw = arr[mid];
mx1[mid - 1] = mx2[mid - 1] = 0;
mn1[mid - 1] = mn2[mid - 1] = 0;
mnmx1[mid - 1] = mnmx2[mid - 1] = 0;
_maxw[mid] = _minw[mid] = arr[mid];
for (int i = mid + 1; i <= r; ++i) {
_maxw[i] = max (_maxw[i - 1], arr[i]);
_minw[i] = min (_minw[i - 1], arr[i]);
}
for (int p = mid; p <= r; ++p) {
mx1[p] = add (mx1[p - 1], mul (_maxw[p], (p + 1)));
mx2[p] = add (mx2[p - 1], _maxw[p]);
mn1[p] = add (mn1[p - 1], mul (_minw[p], (p + 1)));
mn2[p] = add (mn2[p - 1], _minw[p]);
mnmx1[p] = add (mnmx1[p - 1], mul (_maxw[p], mul (_minw[p], (p + 1))));
mnmx2[p] = add (mnmx2[p - 1], mul (_maxw[p], _minw[p]));
}
for (int i = mid; i >= l; --i) {
maxw = max (maxw, arr[i]);
minw = min (minw, arr[i]);
int p1 = get_maxp (maxw, mid + 1, r); // [mid + 1, r]内第一个比maxw大的地方
int p2 = get_minp (minw, mid + 1, r); // [mid + 1, r]内第一个比minw小的地方
if (p1 > p2) swap (p1, p2); // 不关注大小,主要看划分
// cout << p1 << " " << p2 << endl;
ans = add (ans, mul (1ll * (p1 - mid - 1) * (p1 + mid - i * 2 + 2) / 2, mul (minw, maxw))); // Part 1
if (arr[p1] > maxw) {
ans = add (ans, mul (minw, add (add (mx1[p2 - 1], -mx1[p1 - 1]), -mul (i, add (mx2[p2 - 1], -mx2[p1 - 1])))));
} else {
ans = add (ans, mul (maxw, add (add (mn1[p2 - 1], -mn1[p1 - 1]), -mul (i, add (mn2[p2 - 1], -mn2[p1 - 1])))));
}
if (p2 <= r) {
ans = add (ans, add (add (mnmx1[r], -mnmx1[p2 - 1]), -mul (i, add (mnmx2[r], -mnmx2[p2 - 1]))));
}
}
} signed main () {
// freopen ("data.in", "r", stdin);
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
}
cdq (1, n);
// cout << ans << endl;
cout << (((ans % Mod) + Mod) % Mod) << endl;;
}

最新文章

  1. ExtJS 数据模型
  2. CentOS_PHP_NGINX_FastCGI
  3. cf 二分图
  4. 全新的手势,侧滑返回、全局右滑返回都OUT啦!
  5. hyper-v新内容
  6. linux shell编程总结
  7. 排行榜妙用——CSS计数器
  8. flex布局之兼容
  9. Mac下查看已安装的jdk版本及其安装目录
  10. Nodejs一键实现微信内打开网页url自动跳转外部浏览器访问的功能
  11. consul kv使用介绍
  12. 功能比较全的StackExchange.Redis封装帮助类(.Net/C#)
  13. Python_内置函数之zip
  14. mysql 清空表——truncate 与delete的区别
  15. js的轮播效果
  16. jenkins启动appium服务
  17. Javascript核心对象
  18. mysql的一些 参数查询
  19. windows程序设计.窗口.
  20. sqlserver ssms ctrl+e快捷键问题

热门文章

  1. 阶段3 2.Spring_08.面向切面编程 AOP_3 spring基于XML的AOP-编写必要的代码
  2. Java学习之==&gt;注解
  3. 浏览器从输入URL到渲染出页面发生了什么
  4. Logistic回归基础篇之梯度上升算法
  5. java中抽象类、接口及区别
  6. 定时任务crontab命令
  7. CentOS7设置集群环境SSH免密访问
  8. 小记---------linux远程连接集群内其他机器mysql库
  9. 小记---------有关hadoop的HDFS命令行操作
  10. python3的一些文件操作的脚手架