题面

洛谷

你有一个长度为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分治]的更多相关文章

  1. 【BZOJ3745】[Coci2015]Norma cdq分治

    [BZOJ3745][Coci2015]Norma Description Input 第1行,一个整数N: 第2~n+1行,每行一个整数表示序列a. Output 输出答案对10^9取模后的结果. ...

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

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

  3. 【BZOJ3745】Norma(CDQ分治)

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

  4. 【CF526F】Pudding Monsters cdq分治

    [CF526F]Pudding Monsters 题意:给你一个排列$p_i$,问你有对少个区间的值域段是连续的. $n\le 3\times 10^5$ 题解:bzoj3745 Norma 的弱化版 ...

  5. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  6. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  7. HDU5618 & CDQ分治

    Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...

  8. 初识CDQ分治

    [BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 200 ...

  9. HDU5322 Hope(DP + CDQ分治 + NTT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...

随机推荐

  1. (第十三周)Final阶段用户调查报告

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 用户调查报告 调查时间:2016年12月1日  21:00——2016年12月3日  12:00 项目分享链接 ...

  2. mysql数据的导入和导出

    一. mysqldump工具基本用法,不适用于大数据备份   1. 备份所有数据库: mysqldump -u root -p --all-databases > all_database_sq ...

  3. 注入技术--LSP劫持注入

    1.原理 简单来说,LSP就是一个dll程序. 应用程序通过winsock2进行网络通信时,会调用ws2_32.dll的导出函数,如connect,accept等. 而后端通过LSP实现这些函数的底层 ...

  4. 图片转字符画 【学习ing】

    1.创建ascii.py 2. 下面是 ascii.py 的完整代码: from PIL import Image import argparse #命令行输入参数处理 parser = argpar ...

  5. 6-1 Quantifiers

    1 Quantifiers are used to describe the number or amount of something. Certain quantifiers are used w ...

  6. 关于spring的源码的理解

    从最基础的Hello World开始. spring的Hello World就三行代码: public void test() { ApplicationContext context = new C ...

  7. cmd远程连接oracle数据库

  8. zepto的extend

    类型判断 var class2type = {},toString = class2type.toString,$={}; //判断类型 function type(obj) { return obj ...

  9. tensorflow实现基于LSTM的文本分类方法

    tensorflow实现基于LSTM的文本分类方法 作者:u010223750 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实 ...

  10. python学习 第二天

    一.变量 1.变量名: 数字,字母,下划线 alex1=123 sb=“alex” a_lex=“sb” 不能以数字开头 lalex 变量名不是python内部的关键字 {‘and’,'as','as ...