博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EZOJ #77
阅读量:5763 次
发布时间:2019-06-18

本文共 1931 字,大约阅读时间需要 6 分钟。

分析

一个比较神奇的思路

我们考虑分治,对于每一个区间[le,ri]我们计算这个区间中左端点属于[le,mid],右端点属于[mid+1,ri]的情况对答案的贡献

我们求左半个区间的最大最小值的后缀信息以及右半个区间的最大最小值的前缀信息

于是我们发现在左半面最大值越来越小、最小值越来越大,右半面反之

于是我们枚举左端点,并由这个点i找到它在右半个区间对应的p和q

p表示右面最靠左的大于premax[i]的点,q表示右面最靠左的小于premin[i]的点

然后我们分p<=q和p>q两种情况统计答案即可

注意为了方便起见我们提前处理右半个区间最大值、最小值、最大值乘最小值这三个值的前缀和信息

代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int mod = 998244353;int n,a[500100],premin[500100],surmin[500100],premax[500100],surmax[500100],Ans;int s1[500100],s2[500100],s3[500100];inline void go(int le,int ri){ if(le==ri){ Ans=(Ans+(long long)a[le]*a[le]%mod)%mod; return; } int i,mid=(le+ri)>>1,p=mid+1,q=mid+1; premin[mid]=premax[mid]=surmin[mid]=surmax[mid]=a[mid]; for(i=mid-1;i>=le;i--){ premin[i]=min(premin[i+1],a[i]); premax[i]=max(premax[i+1],a[i]); } for(i=mid+1;i<=ri;i++){ surmin[i]=min(surmin[i-1],a[i]); surmax[i]=max(surmax[i-1],a[i]); } s1[mid]=s2[mid]=s3[mid]=0; for(i=mid+1;i<=ri;i++){ s1[i]=(s1[i-1]+surmax[i])%mod; s2[i]=(s2[i-1]+surmin[i])%mod; s3[i]=(s3[i-1]+(long long)surmin[i]*surmax[i]%mod)%mod; } for(i=mid;i>=le;i--){ while(surmax[p]
<=ri)p++; while(surmin[q]>premin[i]&&q<=ri)q++; int tot=0; if(p<=q){ tot=(long long)(p-mid-1)*premin[i]%mod*premax[i]%mod; tot=(tot+(long long)premin[i]*((s1[q-1]-s1[p-1])%mod+mod)%mod)%mod; tot=(tot+((s3[ri]-s3[q-1])%mod+mod)%mod)%mod; }else { tot=(long long)(q-mid-1)*premin[i]%mod*premax[i]%mod; tot=(tot+(long long)premax[i]*((s2[p-1]-s2[q-1])%mod+mod)%mod)%mod; tot=(tot+((s3[ri]-s3[p-1])%mod+mod)%mod)%mod; } Ans=(Ans+tot)%mod; } go(le,mid),go(mid+1,ri); return;}int main(){ int i,j,k; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&a[i]); go(1,n); printf("%d\n",Ans); return 0;}

转载于:https://www.cnblogs.com/yzxverygood/p/9880197.html

你可能感兴趣的文章
数据库访问方式
查看>>
Leetcode 4. Median of Two Sorted Arrays
查看>>
99乘法表
查看>>
Linux下USB驱动框架分析【转】
查看>>
为什么linux下多线程程序如此消耗虚拟内存【转】
查看>>
Linux用户空间与内核空间(理解高端内存)【转】
查看>>
使用gcc的-finstrument-functions选项进行函数跟踪【转】
查看>>
设备树解析【转】
查看>>
iOS系统知识架构(转)
查看>>
Daily Scrum - 11/26
查看>>
Android项目结构 以及体系结构
查看>>
深入浅出设计模式&研磨设计模式
查看>>
centos6上安装docker
查看>>
【作业6】结构体
查看>>
数据库的导入导出
查看>>
In与Exists的区别
查看>>
[bzoj2870]最长道路tree
查看>>
八款开源 Android 游戏引擎 (巨好的资源)
查看>>
性能术语
查看>>
HTTP模块SuperAgent
查看>>