NORMA2 - Norma [cdq分治]
题面
你有一个长度为n的序列,定义这个序列中每个区间的价值是
\(Cost(i,j)=Min(Ai...Aj)∗Max(Ai...Aj)∗(j−i+1)Cost(i,j)=Min(A_{i}...A_{j})*Max(A_{i}...A_{j})*(j-i+1)\)
其中,\(i,j\)是区间的两个端点。
现在请你求出给定序列所有区间的价值之和。
\(n \leq 5e5\)
统计所有子区间 考虑cdq分治
左区间对右区间的贡献如何计算?
用一个cur从mid到L扫左区间
mn,mx表示[cur, mid]的最小值和最大值
对于每一个cur 维护在右区间的两个位置p, q
p表示[mid + 1, p - 1]的数都大于等于mn 而a[p] < mn
q表示[mid + 1, q - 1]的数都小于等于mx 而a[q] > mx
很明显p,q都满足单调性 那么复杂度就可以控制在线性了
当p<q时
对于右区间被分成的三个区间[mid + 1, p - 1], [p, q - 1], [q, R]
mn,mx对这几个区间的贡献推一下式子就好啦
式子参考
对了 注意L==R时计算单点贡献
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 5e5 + 5;
const int inf = 0x3f3f3f3f;
const long long P = 1e9;
int n;
long long a[N], ans, s1[N], s2[N], s3[N], s4[N], s5[N], s6[N];
/*
s1 max * min * i
s2 max * min
s3 min * i
s4 min
s5 max * i
s6 max
*/
inline long long Sum(long long L, long long R){
return (L + R) * (R - L + 1) / 2ll % P;
}
inline void add(long long x){
ans = (ans + x %P) % P;
}
void cdq(int L, int R){
if(L == R) {add(a[L] * a[L] % P); return ;}
int mid = L + ((R - L) >> 1);
cdq(L, mid); cdq(mid + 1, R);
long long mx = 0, mn = inf;
s1[mid] = s2[mid] = s3[mid] = s4[mid] = s5[mid] = s6[mid] = 0;
//printf("----------------\n");
for(int i = mid + 1; i <= R; ++i){
mx = max(a[i], mx), mn = min(a[i], mn);
s1[i] = (mn * mx %P * i %P + s1[i -1]) %P;
s2[i] = (mn * mx %P + s2[i -1])%P;
s3[i] = (mn * i %P + s3[i -1])%P;
s4[i] = (mn + s4[i -1]) %P;
s5[i] = (mx * i %P + s5[i -1])%P;
s6[i] = (mx + s6[i -1]) %P;
//printf("%lld %lld %lld %lld %lld %lld %lld %lld\n", mn, mx, s1[i], s2[i], s3[i], s4[i], s5[i], s6[i]);
}
mn = inf, mx = 0;
for(int p = mid + 1, q = mid + 1, i = mid; i >= L; --i){
mx = max(a[i], mx), mn = min(a[i], mn);
while(p <= R && a[p] >= mn) ++p;
while(q <= R && a[q] <= mx) ++q;//边界
if(p < q){
add(mx * mn %P * Sum(mid - i + 2, p - i) %P);
add(mx * (s3[q - 1] - s3[p - 1]) %P + P - mx * (i - 1) %P * (s4[q - 1] - s4[p - 1]) %P);
add((s1[R] - s1[q - 1]) + P - 1ll * (i - 1) * (s2[R] - s2[q - 1]) % P);
}
else{
add(mx * mn %P * Sum(mid - i + 2, q - i) %P);
add(mn * (s5[p - 1] - s5[q - 1]) %P + P - mn * (i - 1) %P * (s6[p - 1] - s6[q - 1]) %P);
add((s1[R] - s1[p - 1]) + P - 1ll * (i - 1) * (s2[R] - s2[p - 1]) % P);
}
}
//printf("%lld %d %d\n", ans, L, R);
}
int main(){
scanf("%d", &n);
a[0] = 0, a[n + 1] = inf;
for(int i = 1; i <= n; ++i){
scanf("%lld", &a[i]);
}
cdq(1, n);
printf("%lld", (ans %P + P) % P);
return 0;
}
NORMA2 - Norma [cdq分治]的更多相关文章
- 【BZOJ3745】[Coci2015]Norma cdq分治
[BZOJ3745][Coci2015]Norma Description Input 第1行,一个整数N: 第2~n+1行,每行一个整数表示序列a. Output 输出答案对10^9取模后的结果. ...
- 洛谷SP22343 NORMA2 - Norma(分治,前缀和)
洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...
- 【BZOJ3745】Norma(CDQ分治)
[BZOJ3745]Norma(CDQ分治) 题面 BZOJ 洛谷 题解 这种问题直接做不好做,显然需要一定的优化.考虑\(CDQ\)分治. 现在唯一需要考虑的就是跨越当前中间节点的所有区间如何计算答 ...
- 【CF526F】Pudding Monsters cdq分治
[CF526F]Pudding Monsters 题意:给你一个排列$p_i$,问你有对少个区间的值域段是连续的. $n\le 3\times 10^5$ 题解:bzoj3745 Norma 的弱化版 ...
- 【教程】简易CDQ分治教程&学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- BZOJ 2683 简单题 ——CDQ分治
[题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...
- HDU5618 & CDQ分治
Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...
- 初识CDQ分治
[BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 200 ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
随机推荐
- A direct formulation for sparse PCA using semidefinite programming
目录 背景 Sparse eigenvectors(单个向量的稀疏化) 初始问题(low-rank的思想?) 等价问题 最小化\(\lambda\) 得到下列问题(易推) 再来一个等价问题 条件放松( ...
- Python入门-用户登录程序升级版
编写登陆接口 基础需求: 让用户输入用户名密码 认证成功后显示欢迎信息 输错三次后退出程序 升级需求: 可以支持多个用户登录 (提示,通过列表存多个账户信息) 用户3次认证失败后,退出程序,再次启动程 ...
- [2019BUAA软工助教]第一次阅读 - 小结
[2019BUAA软工助教]第一次阅读 - 小结 一.评分规则 总分 16 分,附加 2 分,共 18 分 markdown格式统一且正确 - 2分 不统一:扣 1 分 不正确:扣 1 分(例如使用代 ...
- 这款APP太像微信 腾讯起诉索赔1000万
去年8月,“币应”(inChat)APP上线,号称是一款原创的区块链加密通讯工具,而界面与微信极为相似,图标是白配绿色调,内部界面几乎一模一样,通讯录.朋友圈的界面完全相同.里面的小游戏,也从微信拿来 ...
- EF内容记录_EF连接Mysql版本问题
EF连接MySQL可用版本,由于EF.MySQLConnection.mysql-for-visualstudio.VS版本.MySQL.Data.MySQL.Data.Entity版本问题较花时间, ...
- react组件传值传方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mysql5.7 的 user表的密码字段从 password 变成了 authentication_string
来源: http://www.zhimengzhe.com/shujuku/other/267631.html 感觉还是挺坑的 自己没了解清楚 就动手 转帖一下 mark 一下. 1.首先停止正在运行 ...
- java中级——集合框架【4】-Collections
Collections 首先我们要知道Collections是一个类,容器的工具类,就如同Arrays是数组的工具类 反转 reverse 使List中的数据发生发转 package cn.jse.c ...
- Linux基础学习(11)--Shell编程
第十一章——Shell编程 一.基础正则表达式 1.正则表达式与通配符(*,?,[ ]): 2.基础正则表达式: 二.字符截取命令 1.cut字段提取命令: 空格分割时,不知道空格有多少个,无法分割行 ...
- groovy安装 ideal
参考:https://blog.csdn.net/newbie_907486852/article/details/80879745 (1) 首先下载groovy: https://gradle.or ...