【刷题】BZOJ 3745 [Coci2015]Norma
Description
Input
第1行,一个整数N;
第2~n+1行,每行一个整数表示序列a。
Output
输出答案对10^9取模后的结果。
Sample Input
4
2
4
1
4
Sample Output
109
【数据范围】
N <= 500000
1 <= a_i <= 10^8
Solution
这题目好麻烦
考虑所有子区间问题的贡献可以考虑分治
假设当前到达 \(l,r\) 区间,计算跨过 \(mid\) 的贡献
一个指针 \(x\) 从 \(mid\) 往 \(l\) 枚举,枚举的过程中可以维护 \(a\) 和 \(b\) ,分别代表 \([x,mid]\) 的最小值和最大值
再来两个指针 \(p,q\) ,从 \(mid\) 开始往右走,保证 \([mid+1,p]\) 的最小值是 \(a\) ,\([mid+1,q]\) 的最大值是 \(b\) 的最大位置
那么对于当前的 \(x\) 位置,根据右端点的不同,出现了三种区间
- 右端点小于等于 \(\min \{ p,q \}\) ,这种区间的最小值最大值分别就是 \(a,b\) ,直接算就好了
- 右端点在 \((\min \{p,q\} ,\max \{p,q\}]\) ,这种区间还要分两种情况,不过其本质是一样的。对于这种区间,我们知道了一个最值,而剩下的最值不知道,这样的话,把式子推出来 \(\sum_{y=\min \{p, q\}+1}^{\max \{p, q\}} (\min_{k = mid}^{y} a_k) \times(y - x + 1) \times b\) (这里是假设 \(p<q\) ),拆开后,可以发现预处理两个前缀和就好了
- 右端点大于 \(\max \{p,q\}\) ,这种区间也还要推式子,\(\sum_{y=\max \{p, q\}+1}^{r} (\min_{k = mid}^{y} a_k) (\max_{k = mid}^{y} a_k) \times(y - x + 1)\) ,拆开后又发现是某些个前缀和的加加减减,预处理就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=500000+10,Mod=1e9;
int n,a[MAXN],Mnr[MAXN],Mxr[MAXN];
ll sMn[MAXN],sMx[MAXN],mMn[MAXN],mMx[MAXN],sMxMn[MAXN],mMxMn[MAXN],ans;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void solve(int l,int r)
{
if(l==r)
{
(ans+=1ll*a[l]*a[r]%Mod)%=Mod;
return ;
}
int Mid=(l+r)>>1,p=Mid,q=Mid,Mnl=a[Mid],Mxl=a[Mid];
solve(l,Mid);solve(Mid+1,r);
sMn[Mid]=sMx[Mid]=mMn[Mid]=mMx[Mid]=sMxMn[Mid]=mMxMn[Mid]=0;
Mnr[Mid+1]=sMn[Mid+1]=Mxr[Mid+1]=sMx[Mid+1]=a[Mid+1];
mMn[Mid+1]=mMx[Mid+1]=1ll*a[Mid+1]*(Mid+1)%Mod;
sMxMn[Mid+1]=1ll*a[Mid+1]*a[Mid+1]%Mod;
mMxMn[Mid+1]=1ll*a[Mid+1]*a[Mid+1]%Mod*(Mid+1)%Mod;
for(register int i=Mid+2;i<=r;++i)
{
Mnr[i]=min(Mnr[i-1],a[i]);
Mxr[i]=max(Mxr[i-1],a[i]);
sMn[i]=(sMn[i-1]+Mnr[i])%Mod;
sMx[i]=(sMx[i-1]+Mxr[i])%Mod;
mMn[i]=(mMn[i-1]+1ll*Mnr[i]*i%Mod)%Mod;
mMx[i]=(mMx[i-1]+1ll*Mxr[i]*i%Mod)%Mod;
sMxMn[i]=(sMxMn[i-1]+1ll*Mnr[i]*Mxr[i]%Mod)%Mod;
mMxMn[i]=(mMxMn[i-1]+1ll*Mnr[i]*Mxr[i]%Mod*i%Mod)%Mod;
}
for(register int x=Mid;x>=l;--x)
{
chkmax(Mxl,a[x]);chkmin(Mnl,a[x]);
while(p<r&&Mnr[p+1]>=Mnl)++p;
while(q<r&&Mxr[q+1]<=Mxl)++q;
int lt=min(p,q),mt=max(p,q);
(ans+=1ll*(1ll*(Mid-x+2+lt-x+1)*(lt-Mid)/2)*Mxl%Mod*Mnl%Mod)%=Mod;
if(p<q)(ans+=(1ll*Mxl*(mMn[mt]-mMn[lt]+Mod)%Mod-1ll*(x-1)*Mxl%Mod*(sMn[mt]-sMn[lt]+Mod)%Mod+Mod)%Mod)%=Mod;
if(p>q)(ans+=(1ll*Mnl*(mMx[mt]-mMx[lt]+Mod)%Mod-1ll*(x-1)*Mnl%Mod*(sMx[mt]-sMx[lt]+Mod)%Mod+Mod)%Mod)%=Mod;
(ans+=((mMxMn[r]-mMxMn[mt]+Mod)%Mod-1ll*(x-1)*(sMxMn[r]-sMxMn[mt]+Mod)%Mod+Mod)%Mod)%=Mod;
}
}
int main()
{
read(n);
for(register int i=1;i<=n;++i)read(a[i]);
solve(1,n);
write(ans,'\n');
return 0;
}
【刷题】BZOJ 3745 [Coci2015]Norma的更多相关文章
- BZOJ 3745: [Coci2015]Norma(分治)
题意 给定一个正整数序列 \(a_1, a_2, \cdots, a_n\) ,求 \[ \sum_{i=1}^{n} \sum_{j=i}^{n} (j - i + 1) \min(a_i,a_{i ...
- bzoj 3745 [Coci2015]Norma——序列分治
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3745 如果分治,就能在本层仅算过 mid 的区间了. 可以从中间到左边地遍历左边,给右边两个 ...
- bzoj 3745: [Coci2015]Norma
Description Solution 考虑分治: 我们要统计跨越 \(mid\) 的区间的贡献 分最大值和最小值所在位置进行讨论: 设左边枚举到了 \(i\),左边 \([i,mid]\) 的最大 ...
- bzoj 3745: [Coci2015]Norma【分治】
参考:https://blog.csdn.net/lych_cys/article/details/51203960 真的不擅长这种-- 分治,对于一个(l,r),先递归求出(l,mid),(mid+ ...
- 【刷题】BZOJ 2407 探险
Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...
- 【刷题】BZOJ 4543 [POI2014]Hotel加强版
Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...
- 【刷题】BZOJ 4316 小C的独立集
Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...
- 【刷题】BZOJ 4176 Lucas的数论
Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
随机推荐
- Oracle 批量修改某个用户下表的表空间
说明:一般来说要修改表的表空间需要同时修改表的表空间和其对应的索引表空间,并且在修改含有BOLB字段的表的表空间时又不一样,具体请参考末尾的链接 思路:拼凑一个满足条件的批处理查询语句,将查询的结果复 ...
- 简单叨叨bootstrap按钮无限层级下拉菜单的实现
0.写在前面的话 最近看书都懈怠了,又正值新项目,虽说并不是忙得不可开交,好吧我老实交待,我就是偷懒了其实,博客也没更.言归正传,对于前端的不熟悉现在确实是个让我头疼的事情,以至于一些功能要在网络上漫 ...
- Features + Git + Drush,打造你的Drupal开发与维护标准工作流
还在为如何将本地的开发工作如何部署到生产环境而皱眉头?本文以实战历程教你如何一步步将你的工作成果从开发环境部署到生产环境. 如题所示,需要用到Features, Git, Drush:如果你还不知道他 ...
- BYTE数组与16进制字符串互转
//字节数组转换为HEX 字符串const string Byte2HexString(const unsigned char* input, const int datasize) { ]; ; j ...
- [转]申瓯 JSY2000-06 程控电话交换机呼叫转移设置
说明:若申瓯程控电话交换机分机有事不在位置上或遇忙分机正忙时为使某些重要来话不丢失,可设置将呼入本机的电话转移至其他分机及公网固定电话或手机.电话交换机使用了本功能不管分机用户在什么地方都能接听到办公 ...
- IT简历
对很多IT毕业生来说,写简历投简历是必不可少的.一个好的简历已是面试成功的一半. 简历的目的是为了引人注意,争取让HR主动联系你去面试,不可避免的在简历中掺杂着一些水分,但是能争取到面试机会,再与HR ...
- [SHELL]输入输出重定向与管道
一 . 输出重定向(将命令的输出重定向到文件): ls -al > test 以覆盖的方式写入 ls -al >> test 以追加的方式写入 二 . 输入重定向(将文件的内容重定向 ...
- Grin v0.5在Ubuntu下的安装和启动
Grin和bitcoin一样也是一种点对点的现金交易系统,但它通过零和验证算法,使得双方的交易金额不会被第三方知晓,让它在隐私保护方面更强.其官方的介绍是: 所有人的电子交易,没有审查或限制.并提出它 ...
- Notes of Daily Scrum Meeting(12.21)
今天的燃尽图把周六的进度加了进来,由于我的失误没有及时更新TFS,所以出现了一些错误,向大家道歉. 下面是今天的任务总结: 团队成员 今日团队工作 陈少杰 继续进行网络连接的调试 王迪 测试搜索的功能 ...
- LINUX基础实验报告
实验一:主要是介绍Linux系统概况,无运行代码. 实验二:Linux的基本操作 重要知识点 [Tab] 使用Tab键来进行命令补全,Tab键一般键盘是在字母Q旁边,这个技巧给你带来的最大的好处就是当 ...