题解-COCI-2015Norma
Problem
题意概要:给定一个正整数序列 \(\{a_i\}\),求
\]
\(n\leq 5\times 10^5\)
Solution
这题正解是一个完美的 \(O(n\log n)\) 分治,但比较麻烦,鉴于这个分治做法已经漫天飞了,所以这里不讲那个算法
我在考场上在最后二十分钟想到了并打出了另一个分治做法,非常很好写跑得也很快,最终可以 AC
可以考虑对于一个序列 \(\{a_i\}\),找到其最大值 \(mx\) 与最小值 \(mi\),有大量区间都是以这两点为最值点的,而同时这些区间的左右端点分别都是连续的,所以可以考虑将这些区间一起计算
具体的,若找到的最大值与最小值分别在 \(p_1,p_2\) 取到(不妨设 \(p_1\leq p_2\)),则以这两者为最值点的区间 \([l,r]\) 满足 \(1\leq l\leq p_1,p_2\leq r\leq n\),这些区间的长度和可以 \(O(1)\) 算出,也即可以 \(O(1)\) 算出这些区间的贡献
进一步的,需要加上其他不是 同时以这两者为最值点 的区间贡献。设统计左右端点都在 \([l,r]\) 内的区间贡献也即刚刚这一步处理为函数 \(f(l,r)\),则其他区间的贡献即 \(f(l,p_2-1)+f(p_1+1,r)-f(p_1+1,p_2-1)\)(由于前面两个式子中重复计算了左右端点都在 \([p_1+1,p_2-1]\) 内的区间贡献,所以需要第三个函数去减去这部分多余的贡献)
所以现在可以得到一个基本的做法(统计 \([l,r]\) 区间):
- \(O(1)\) 找到区间最大最小值所在位置 \(p_1,p_2(p_1\leq p_2)\)
- \(O(1)\) 统计左端点在 \([l,p_1]\)、右端点在 \([p_2,r]\) 的区间的贡献
- 分治统计区间 \([l,p_2-1],[p_1+1,r]\),并减去 \([p_1+1,p_2-1]\) 的答案
这个做法慢成龟龟,然后我灵机一动:分治下去的区间不是会继续使用当前最值点为最值点吗?(即 \([l,p_2-1]\) 会使用 \(p_1\) 为最值点,进而可能再次调用区间 \([p_1+1,p_2-1]\),这里的统计就冗余了,如果加个记忆化那么原来每次分出三个区间就可以均摊成两个了……)
然后就加了一下 \(map\) 的记忆化,极限数据只需要 \(0.4s\)
之前证了一波伪的复杂度 \(O(n\log n)\),后来被同校 dalao 精心卡掉了 虽然构造了一个多小时
实际上复杂度是 \(O(n^2\log n)\) 的,那个 \(\log\) 还是 \(map\) 的复杂度 没错这是个暴力,但很难卡满,在考试中、spoj和bzoj上都没能卡掉我♪(∇*)
实际运行效率很高,未经st表优化的代码在bzoj上跑到 \(\mathrm{rank6}\),比我写的正解快一倍,同时代码也很短很好写 毕竟是在十分钟内写完调完的,只有 \(\mathrm{1.2k}\)
Code
由于想到这个解法时时间紧迫,没来得及写 \(st\) 表做 \(\mathrm{rmq}\) 但还是过掉了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <typename _tp> inline _tp read(_tp&x){
char c11=getchar(),ob=0;x=0;
while(c11!='-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}
const int N=501000,p=1e9,inf=0x3f3f3f3f;
int a[N],n;
map <int,int> mp[N];
inline int getsum(int l,int r){return 1ll*(l+r)*(r-l+1)/2%p;}
inline int qm(int x){while(x<0)x+=p;while(x>=p)x-=p;return x;}
int force(int l,int r){
int res(0);
for(int i=l;i<=r;++i){
int mx=-inf,mi=inf;
for(int j=i;j<=r;++j){
mx=max(mx,a[j]);
mi=min(mi,a[j]);
res=qm(res+1ll*(j-i+1)*mi%p*mx%p);
}
}return res;
}
int solve(int l,int r){
if(l>r)return 0;
if(mp[l].find(r)!=mp[l].end())
return mp[l][r];
if(r-l<=10)
return mp[l][r]=force(l,r);
int mx=-inf,mxd;
int mi=inf,mid;
for(int i=l;i<=r;++i){
if(a[i]>mx)mx=a[i],mxd=i;
if(a[i]<mi)mi=a[i],mid=i;
}
int L=min(mxd,mid),dl=L-l+1;
int R=max(mxd,mid),dr=r-R+1;
int dx=R-L-1,res(0);
if(dl>dr)swap(dl,dr);
for(int i=1;i<=dl;++i)
res=qm(res+getsum(i+dx+1,i+dx+dr));
res=1ll*res*mx%p*mi%p;
return mp[l][r]=qm(res+qm(solve(l,R-1)+solve(L+1,r))-solve(L+1,R-1));
}
int main(){
read(n);
for(int i=1;i<=n;++i)read(a[i]);
printf("%d\n",solve(1,n));
return 0;
}
题解-COCI-2015Norma的更多相关文章
- [SinGuLaRiTy] COCI 2011~2012 #2
[SinGuLaRiTy-1008] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 测试题目 对于所有的题目:Time Limit:1s ...
- 【题解】 Luogu P4312 / SP4155 [COCI 2009] OTOCI / 极地旅行社
原题地址:P4312 [COCI 2009] OTOCI / 极地旅行社/SP4155 OTOCI - OTOCI lct入门难度的题,十分弱智(小蒟蒻说lct是什么,能吃吗?) bridge操作判联 ...
- COCI 2015、2016 1st round 题解(官方)
官方题解: 官方代码: Code-KARTE: #include <cstdio> #include <iostream> #include <cstring> u ...
- BZOJ3188: [Coci 2011]Upit
3188: [Coci 2011]Upit Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 72 Solved: 24[Submit][Status] ...
- [SinGuLaRiTy] COCI 2016~2017 #5
[SinGuLaRiTy-1012] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 最近神犇喜欢考COCI...... 测试题目 对于所有的 ...
- COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution
COCI 2018/2019 CONTEST #2 T4 T5 Solution abstract 花式暴力 #2 T5 Sunčanje 题意 按顺序给你1e5个长方形(左下角坐标&& ...
- bzoj 2223 [Coci 2009]PATULJCI
[Coci 2009]PATULJCI Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1286 Solved: 553[Submit][Status ...
- [luogu]P4312 [COCI 2009] OTOCI / 极地旅行社(LCT)
P4312 [COCI 2009] OTOCI / 极地旅行社 题目描述 不久之前,Mirko建立了一个旅行社,名叫"极地之梦".这家旅行社在北极附近购买了N座冰岛,并且提供观光服 ...
- 【题解】Dvoniz [COCI2011]
[题解]Dvoniz [COCI2011] 没有传送门,只有提供了数据的官网. [题目描述] 对于一个长度为 \(2*K\) 的序列,如果它的前 \(K\) 个元素之和小于等于 \(S\) 且后 \( ...
- 题解:[COCI2011-2012#5] BLOKOVI
题解:[COCI2011-2012#5] BLOKOVI Description PDF : https://hsin.hr/coci/archive/2011_2012/contest5_tasks ...
随机推荐
- C++通用WMI接口实现获取Windows操作系统内核版本号
作为一名Windows开发者,能熟练掌握WMI技术,在开发Windows应用程序的时候往往能够事半功倍.今天来给大家分享一个使用WMI来获取Windows操作系统内核版本号的例子. 首先我们打开WMI ...
- iframe 高度自适应
<iframe id="InputDetail" src style="width:100%"></iframe> <script ...
- asp.net core 2.2 中的过滤器/筛选器(上)
ASP.NET Core中的过滤器/筛选器 通过使用 ASP.NET Core MVC 中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码. 注意:本主题不适用于 Razor 页面. ASP. ...
- 红米Note 4X详细刷成开发版开启ROOT超级权限的教程
小米的手机不同手机型号正常情况下官方网站都提供两个不同的版本,大概分为稳定版和开发版,稳定版没有提供Root超级权限管理,开发版中就开启了Root超级权限,很多情况我们需要使用的一些功能强大的app, ...
- Centos下MariaDB操作
MariaDB简介 MariaDB是mysql数据库的一个分支,操作几乎和mysql一样 MariaDB安装.启动.停止 # 安装 yum -y install mariadb mariadb-ser ...
- spring 中的设计模式
https://mp.weixin.qq.com/s?__biz=MzU0MDEwMjgwNA==&mid=2247485205&idx=1&sn=63455d2313776d ...
- 二、docker的安装和基本命令
一.docker的安装 1.安装依赖 # yum install -y yum-utils device-mapper-persistent-data 2.设置yum源 # yum-config-ma ...
- python计算素数和
计算输入两个正整数x,y(x<=y,包括x,y)素数和.函数isPrime用以判断一个数是否素数,primeSum函数返回素数和 以下为源码 def isPrime(n) : for i ...
- 0412ooday01.txt=============对象和类(上)
对象和类(上) 面向对象程序设计:面向过程的结构化程序设计.什么是抽象数据类型.什么是类 定义一个类:定义类的成员变量.定义类的方法 创建并使用对象:使用new关键字创建对象.引用类型变量.访问对象的 ...
- DirectX11 With Windows SDK--27 计算着色器:双调排序
前言 上一章我们用一个比较简单的例子来尝试使用计算着色器,但是在看这一章内容之前,你还需要了解下面的内容: 章节 26 计算着色器:入门 深入理解与使用缓冲区资源(结构化缓冲区/有类型缓冲区) Vis ...