要命的题目。

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

枚举过每一个\(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;;
}

BZOJ3745 / SP22343 NORMA2 - Norma 分治,CDQ分治的更多相关文章

  1. 【BZOJ3745】Norma(CDQ分治)

    [BZOJ3745]Norma(CDQ分治) 题面 BZOJ 洛谷 题解 这种问题直接做不好做,显然需要一定的优化.考虑\(CDQ\)分治. 现在唯一需要考虑的就是跨越当前中间节点的所有区间如何计算答 ...

  2. [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解

    原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...

  3. UOJ #7 NOI2014购票(点分治+cdq分治+斜率优化+动态规划)

    重写一遍很久以前写过的题. 考虑链上的问题.容易想到设f[i]为i到1的最少购票费用,转移有f[i]=min{f[j]+(dep[i]-dep[j])*p[i]+q[i]} (dep[i]-dep[j ...

  4. 点分治&cdq分治 总结

    游荡的孤高灵魂不需要羁绊之处. 洛谷题单 点分治 前置芝士 树的重心 树分治 例题略解 P3806 [模板]点分治1 板子题,先暴力找到整棵树的重心,然后先求出重心到各点的距离,进而算出他所在树的各个 ...

  5. 洛谷SP22343 NORMA2 - Norma(分治,前缀和)

    洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...

  6. [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1749  Solved: 885[Submit][Status][ ...

  7. 【BZOJ4237】稻草人(CDQ分治,单调栈)

    [BZOJ4237]稻草人(CDQ分治,单调栈) 题面 BZOJ 题解 \(CDQ\)分治好题呀 假设固定一个左下角的点 那么,我们可以找到的右下角长什么样子??? 发现什么? 在右侧是一个单调递减的 ...

  8. 一篇自己都看不懂的CDQ分治&整体二分学习笔记

    作为一个永不咕咕咕的博主,我来更笔记辣qaq CDQ分治 CDQ分治的思想还是比较简单的.它的基本流程是: \(1.\)将所有修改操作和查询操作按照时间顺序并在一起,形成一段序列.显然,会影响查询操作 ...

  9. 浅谈CDQ分治与偏序问题

    初识CDQ分治 CDQ分治是一个好东西,一直听着dalao们说所以就去学了下. CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. ...

随机推荐

  1. 【Java基础】对象序列化与读写

    package com.test.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

  2. 关系/对象映射 多对多关系(@ManyToMany 注释)【重新认识】

    old: @ManyToMany 注释:表示此类是多对多关系的一边, mappedBy 属性定义了此类为双向关系的维护端, 注意:mappedBy 属性的值为此关系的另一端的属性名. 例如,在Stud ...

  3. java:多线程(代理模式,Thread中的方法,Timer,生产者和消费者)

    *进程:一个正在运行的程序,进程是操作系统分配资源的基本单位,每个进行有独立的内存空间,进程之间切换开销较大. *线程:一个轻量级的进程,线程是任务调度的基本单位,一个进程可以有多个线程, * 系统没 ...

  4. LeetCode.1005-K次取负数组和最大(Maximize Sum Of Array After K Negations)

    这是悦乐书的第376次更新,第403篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第237题(顺位题号是1005).给定一个整数数组A,我们必须按以下方式修改数组:我们选 ...

  5. 快速生成500W测试数据库

    快速生成500W测试数据库: 创建测试表: DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(10) NOT NULL AUTO_ ...

  6. C++ 全局变量 静态变量 全局函数 静态函数

    1. static 变量 静态变量的类型 说明符是static. 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量. 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须 ...

  7. 第八周课程报告&&实验报告六

    Java实验报告 班级 计科一班 学号 20188390 姓名 宋志豪 实验四 类的继承 实验目的 理解异常的基本概念: 掌握异常处理方法及熟悉常见异常的捕获方法. 实验要求 练习捕获异常.声明异常. ...

  8. Hive开发中使用变量的两种方法

    在使用hive开发数据分析代码时,经常会遇到需要改变运行参数的情况,比如select语句中对日期字段值的设定,可能不同时间想要看不同日期的数据,这就需要能动态改变日期的值.如果开发量较大.参数多的话, ...

  9. C++中的类型识别

    1,为什么会提出类型识别概念呢? 1,为什么在 C 语言中没有提出这个概念呢,就是因为在 C++ 中引入了面向对象的特性,面向对象里面有一个非常重要的原则就是赋值兼容性原则: 2,在面向对象中可能出现 ...

  10. centos7下apache启动报错记录

    http重启httpd发生错误,后面按照提示执行systemctl status httpd.service命令 按照提示,继续执行journalctl -xe 这里显示了详细的错误信息,并且给出了解 ...