【BZOJ3745】Norma(CDQ分治)

题面

BZOJ

洛谷

题解

这种问题直接做不好做,显然需要一定的优化。考虑\(CDQ\)分治。

现在唯一需要考虑的就是跨越当前中间节点的所有区间如何计算答案了。

从\(mid\)开始向左枚举左端点,考虑右端点的贡献。那么我们在右侧记录两个指针\(p,q\),分别表示左侧的最大值和最小值第一次改变的位置。这两个指针会把整个序列分成三段。

第一段最大值和最小值都是左侧最大最小值,直接计算区间长度和就好了。

第二段是最大值和最小值中一个被改变了,分情况讨论一下,维护右侧的区间最大最小值就可以直接算了。第三部分是最大值和最小值都被改变了,那么把式子写出来,维护一个前缀就好了。

时间复杂度\(O(nlogn)\)。可能实现要仔细想清楚,可以看看代码。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 500500
#define MOD 1000000000
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int S(int l,int r){return 1ll*(l+r)*(r-l+1)/2%MOD;}
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;if(x<0)x+=MOD;}
int n,ans,a[MAX];
int sm[MAX],sp[MAX],smx[MAX],smn[MAX],smxp[MAX],smnp[MAX],mnv[MAX],mxv[MAX];
void CDQ(int l,int r)
{
if(l==r){add(ans,1ll*a[l]*a[l]%MOD);return;}
int mid=(l+r)>>1;CDQ(l,mid);CDQ(mid+1,r);
int mn=a[mid],mx=a[mid];
sm[mid]=sp[mid]=smx[mid]=smn[mid]=smxp[mid]=smnp[mid]=0;
for(int i=mid+1;i<=r;++i)
if(i==mid+1)
{
mnv[i]=mxv[i]=smx[i]=smn[i]=a[i];
smnp[i]=smxp[i]=1ll*a[i]*i%MOD;
sm[i]=1ll*a[i]*a[i]%MOD;sp[i]=1ll*i*a[i]%MOD*a[i]%MOD;
}
else
{
mnv[i]=min(mnv[i-1],a[i]);
mxv[i]=max(mxv[i-1],a[i]);
add(smn[i]=smn[i-1],mnv[i]);
add(smx[i]=smx[i-1],mxv[i]);
add(smnp[i]=smnp[i-1],1ll*mnv[i]*i%MOD);
add(smxp[i]=smxp[i-1],1ll*mxv[i]*i%MOD);
add(sm[i]=sm[i-1],1ll*mnv[i]*mxv[i]%MOD);
add(sp[i]=sp[i-1],1ll*i*mnv[i]%MOD*mxv[i]%MOD);
}
for(int i=mid,p=mid,q=mid;i>=l;--i)
{
mn=min(mn,a[i]);mx=max(mx,a[i]);
while(p<r&&mnv[p+1]>=mn)++p;
while(q<r&&mxv[q+1]<=mx)++q;
add(ans,1ll*S(mid-i+2,min(p,q)-i+1)*mn%MOD*mx%MOD);
if(p<q)add(ans,((smnp[q]-smnp[p])-1ll*(smn[q]-smn[p])*(i-1)%MOD+MOD)*mx%MOD);
if(q<p)add(ans,((smxp[p]-smxp[q])-1ll*(smx[p]-smx[q])*(i-1)%MOD+MOD)*mn%MOD);
add(ans,(((sp[r]-sp[max(p,q)])-1ll*(sm[r]-sm[max(p,q)])*(i-1)%MOD+MOD)%MOD));
}
}
int main()
{
n=read();
for(int i=1;i<=n;++i)a[i]=read();
CDQ(1,n);printf("%d\n",ans);
return 0;
}

【BZOJ3745】Norma(CDQ分治)的更多相关文章

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

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

  2. NORMA2 - Norma [cdq分治]

    题面 洛谷 你有一个长度为n的序列,定义这个序列中每个区间的价值是 \(Cost(i,j)=Min(Ai...Aj)∗Max(Ai...Aj)∗(j−i+1)Cost(i,j)=Min(A_{i}.. ...

  3. 【CF526F】Pudding Monsters cdq分治

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

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

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

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

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

  6. HDU5618 & CDQ分治

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

  7. 初识CDQ分治

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

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

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

  9. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

随机推荐

  1. Json.NET如何避免循环引用

    Json.NET在将对象序列化为Json字符串的时候,如果对象有循环引用的属性或字段,那么会导致Json.NET抛出循环引用异常. 有两种方法可以解决这个问题: 1.在对象循环引用的属性上打上[Jso ...

  2. JS设置cookie、读取cookie、删除cookie(转载)

    JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的.而cookie是运行在客户端的,所以可以用JS来设置cookie.假设有这样一种情 ...

  3. 【H5】滚动事件(jq)

    $(function(){ console.log($('html,body').scrollTop());  //记录滚动高度(滚动前) }) $('html,body').scroll(funct ...

  4. 解决Android中,禁止ScrollView内的控件改变之后自动滚动 - 转

    问题: 最近在写一个程序界面,有一个scrollVIew,其中有一段内容是需要在线加载的. 当内容加载完成后,ScrollView中内容的长度会发生改变,这时ScrollView会自动下滚,如下图所示 ...

  5. python基础——类定义(转)

    一.类定义: class <类名>: <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性.如果直接使用类名修改其属性,那么将直接影响到已经实例 ...

  6. 基于TLS证书手动部署kubernetes集群(上)

    一.简介 Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S. K8S是Google内部一个叫Borg的容器集群管理系统衍生 ...

  7. 20155202张旭《网络对抗技术》 week1 PC平台逆向破解及Bof基础实践

    20155202张旭<网络对抗技术> week1 PC平台逆向破解及Bof基础实践 1.实践目标: 实践对象:一个名为pwn1的linux可执行文件. 该程序正常执行流程是: main调用 ...

  8. HTML基础之DOM操作

    DOM(Document Object Model 文档对象模型) 一个web页面的展示,是由html标签组合成的一个页面,dom对象实际就是将html标签转换成了一个文档对象.可以通过dom对象中j ...

  9. R绘图 第四篇:绘制箱图(ggplot2)

    箱线图通过绘制观测数据的五数总括,即最小值.下四分位数.中位数.上四分位数以及最大值,描述了变量值的分布情况.箱线图能够显示出离群点(outlier),离群点也叫做异常值,通过箱线图能够很容易识别出数 ...

  10. JVM技术周报第2期

    JVM技术周报第2期 JVM技术周报分享JVM技术交流群的讨论内容,由群内成员整理归纳而成.如果你有兴趣入群讨论,请关注「Java技术精选」公众号,通过右下角菜单「入群交流」加我好友,获取入群详情. ...