题目大意

  给定一个长度为 nnn 的序列 a1,⋯,ana_1,\cdots,a_na1​,⋯,an​,求所有区间的 mexmexmex 平均值之和,即
∑l=1n∑r=lnmex(al,al+1,⋯,ar)r−l+1(mod998244353)\sum_{l=1}^n\sum_{r=l}^n \frac{mex(a_l,a_{l+1},\cdots,a_r)}{r-l+1} \pmod{998244353} l=1∑n​r=l∑n​r−l+1mex(al​,al+1​,⋯,ar​)​(mod998244353)
  1≤n≤5×105,0≤ai≤5×1051 \leq n \leq 5 \times 10^5,~~0 \leq a_i \leq 5 \times 10^51≤n≤5×105,  0≤ai​≤5×105

\\
\\
\\

题解

  这题大概是有两种解法,官方题解是转化成 ∑i=0max⁡{a}∑l≤r[mex(al,⋯,ar)≥i]r−l+1\sum_{i=0}^{\max\{a\}}\sum_{l \leq r} \frac{[mex(a_l,\cdots,a_r) \geq i]}{r-l+1}∑i=0max{a}​∑l≤r​r−l+1[mex(al​,⋯,ar​)≥i]​ 来做,但它比较简略我没搞懂。于是又找到了HOWARLI的做法,我这个就是参考他的。被吊打啦

  有一种传统建模是,左端点从右往左移动,用线段树维护右端点的答案。但是在这题,左端点往左移相当于给若干个序列插入一个元素, mexmexmex 怎么变就很难搞了。

  但是变通一下,左端点从左往右移,就很好搞了。因为这对于 mexmexmex 来说相当于是区间取 min⁡\minmin 的操作。
  当左端点从 i−1i-1i−1 移到 iii,就相当于删去 ai−1a_{i-1}ai−1​,假设 i−1i-1i−1 后面的第一个跟 ai−1a_{i-1}ai−1​ 相同的元素是 anexti−1a_{next_{i-1}}anexti−1​​,那么删去 ai−1a_{i-1}ai−1​ 影响到的右端点范围就是 [i,nexti−1)[i,next_{i-1})[i,nexti−1​)。在这个范围里所有 mexmexmex 值大于 ai−1a_{i-1}ai−1​ 的都会变成 ai−1a_{i-1}ai−1​。
  由于 mexmexmex 是分段递增的,我们在这个范围内找到所有 mexmexmex 值大于 ai−1a_{i-1}ai−1​ 的段,结算它们的贡献,并更新它们。
  假设一个段 [l,r][l,r][l,r],mexmexmex 值为 mmm。对于里面的一个元素 x(x∈[l,r])x~(x \in [l,r])x (x∈[l,r]),它最早在左端点为 ttt 时把 mexmexmex 值更新为 mmm,那么它要结算的贡献就是 m(1x−t+1+⋯+1x−(i−1)+1)m(\frac{1}{x-t+1}+\cdots+\frac{1}{x-(i-1)+1})m(x−t+11​+⋯+x−(i−1)+11​),即 m(sx−t+1−sx−(i−1))m(s_{x-t+1}-s_{x-(i-1)})m(sx−t+1​−sx−(i−1)​)(记 sn=∑i=1n1is_n=\sum_{i=1}^n \frac 1isn​=∑i=1n​i1​)。
  于是用线段树维护一下 mexmexmex 的分段、区间 ∑sx−t+1\sum s_{x-t+1}∑sx−t+1​ 即可。
  每次左端点的移动,最多新增 2 个段,删除若干个段,因此段的总量也是 O(n)O(n)O(n) 的。时间复杂度 O(nlog⁡n)O(n \log n)O(nlogn)。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;typedef long long LL;const int maxn=5e5+5;
const LL mo=998244353;struct TR{int minmex,maxmex;LL st;
};int n,a[maxn];LL Pow(LL x,LL y)
{LL re=1;for(; y; y>>=1, x=x*x%mo) if (y&1) re=re*x%mo;return re;
}int ap[maxn],nxt[maxn],init_mex[maxn];
LL s[maxn],ss[maxn];
void Pre()
{fd(i,n,1){nxt[i]=(!ap[a[i]]) ?n+1 :ap[a[i]];ap[a[i]]=i;}memset(ap,0,sizeof(ap));int mex=0;fo(i,1,n){ap[a[i]]=1;while (ap[mex]) mex++;init_mex[i]=mex;}fo(i,1,n) s[i]=(s[i-1]+Pow(i,mo-2))%mo, ss[i]=(ss[i-1]+s[i])%mo;
}TR tr[4*maxn];
pair<int,int> bz[4*maxn];
TR merge(const TR &a,const TR &b)
{return (TR){min(a.minmex,b.minmex),max(a.maxmex,b.maxmex),(a.st+b.st)%mo};
}
void update(int k,int t,int l,int mid,int r)
{if (!bz[k].first) return;tr[t]=(TR){bz[k].second,bz[k].second,(ss[mid-bz[k].first+1]-ss[l-bz[k].first]+mo)%mo};tr[t+1]=(TR){bz[k].second,bz[k].second,(ss[r-bz[k].first+1]-ss[mid+1-bz[k].first]+mo)%mo};bz[t]=bz[t+1]=bz[k];bz[k]=make_pair(0,0);
}
void tr_js(int k,int l,int r)
{if (l==r){tr[k]=(TR){init_mex[r],init_mex[r],s[r]};return;}int t=k<<1, mid=(l+r)>>1;tr_js(t,l,mid), tr_js(t+1,mid+1,r);tr[k]=merge(tr[t],tr[t+1]);
}
pair<int,int> cx_bs(int k,int l,int r,int x,int z)
{if (l==r) return (tr[k].maxmex>z) ?make_pair(l,tr[k].maxmex) :make_pair(-1,-1) ;int t=k<<1, mid=(l+r)>>1;update(k,t,l,mid,r);return (x<=mid && tr[t].maxmex>z) ?cx_bs(t,l,mid,x,z) :cx_bs(t+1,mid+1,r,x,z);
}
int cx_r(int k,int l,int r,int x,int z)
{if (l==r) return l;int t=k<<1, mid=(l+r)>>1;update(k,t,l,mid,r);return (x<=mid && tr[t+1].minmex>z) ?cx_r(t,l,mid,x,z) :cx_r(t+1,mid+1,r,x,z);
}
LL cx_st(int k,int l,int r,int x,int y)
{if (x<=l && r<=y) return tr[k].st;int t=k<<1, mid=(l+r)>>1;update(k,t,l,mid,r);LL re=0;if (x<=mid) re=cx_st(t,l,mid,x,y);if (mid<y) (re+=cx_st(t+1,mid+1,r,x,y))%=mo;return re;
}
void tr_xg(int k,int l,int r,int x,int y,pair<int,int> z)
{if (x<=l && r<=y){tr[k]=(TR){z.second,z.second,(ss[r-z.first+1]-ss[l-z.first]+mo)%mo};bz[k]=z;return;}int t=k<<1, mid=(l+r)>>1;update(k,t,l,mid,r);if (x<=mid) tr_xg(t,l,mid,x,y,z);if (mid<y) tr_xg(t+1,mid+1,r,x,y,z);tr[k]=merge(tr[t],tr[t+1]);
}int main()
{freopen("average.in","r",stdin);freopen("average.out","w",stdout);scanf("%d",&n);fo(i,1,n) scanf("%d",&a[i]);Pre();tr_js(1,1,n);LL ans=0;fo(i,1,n){if (i>1){for(int l=i, r; l<nxt[i-1]; l=r+1){pair<int,int> t=cx_bs(1,1,n,l,a[i-1]);l=t.first;if (l==-1 || l>=nxt[i-1]) break;r=min(cx_r(1,1,n,l,t.second),nxt[i-1]-1);(ans+=(cx_st(1,1,n,l,r)-ss[r-(i-1)]+mo+ss[l-(i-1)-1])%mo*t.second)%=mo;tr_xg(1,1,n,l,r,make_pair(i,a[i-1]));}}(ans+=cx_st(1,1,n,i,i)*(a[i]==0))%=mo;}printf("%lld\n",ans);
}

【JZOJ4939】平均值 题解相关推荐

  1. 【HDU-2376】Average distance

    [HDU-2376]Average distance 题意: 给你一个树,求树上任意两个点之间的距离的平均值 题解: 就是求出任意两点之间的距离和然后除以边数 "任意两点之间的距离" ...

  2. LuoguP4233 射命丸文的笔记

    题目描述 求所有\(n\)个点带标号强连通竞赛图中哈密顿回路数量的平均值. 题解 因为要求平均数,所以我们可以把分母和分子单开来算. \(n\)个点的所有竞赛图的所有哈密顿回路个数是可以求出来的,就是 ...

  3. 2020 CCPC Wannafly Winter Camp Day2 Div.12——A 托米的字符串【构造、数学】

    题目传送门 题目描述 托米有一个字符串,他经常拿出来玩.这天在英语课上,他学习了元音字母 a , e , i , o , u {a,e,i,o,u} a,e,i,o,u 以及半元音 y {y} y . ...

  4. codeforces 1003A. Polycarp's Pockets,C. Intense Heat(暴力)

    A. Polycarp's Pockets 题目链接:codeforces 1003A 题意:      给n个数,要求相同的数不能放在一个口袋,问最少需要多少个口袋 题解:     求出最多的相同数 ...

  5. Python编程PTA题解——大于身高的平均值

    Python编程PTA题解大全--索引 Description:中小学生每个学期都要体检,要量身高,因为身高可以反映孩子的生长状况.现在,一个班的身高已经量好了,请输出其中超过平均身高的那些身高.程序 ...

  6. zzuli 20级新生周赛(1)题解

    前言:涉及了字符串的题运用了string类,比char要方便很多,建议学习. 文章目录 A.藏头诗 B.画剑 C.商品总数 D. 小"光棍节" E.神秘的123 F.黄河大鲤鱼 G ...

  7. BZOJ 2133 切割(树形DP,树上背包)大概是本题全网第一篇题解 >_<【BZOJ 修复工程】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 BZOJ 2133 切割这道题全网搜不到任何一篇题解 >_< 看评测记录也没有几个人AC- ...

  8. 2018 ACM-ICPC Asia Shenyang Regional Contest 题解(9 / 13)【每日亿题2021/2/24】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.(2018 ACM-ICPC Shenyang J)How Much Memory Your ...

  9. 我花了三个小时写了一道题的六千字题解....(POJ 2888 Magic Bracelet)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 前置知识:小学生都能看懂的群论从入门到升天教程 <群论全家桶> 一道简单的题目 Probl ...

  10. POJ 2976 Dropping tests【二分 最大化平均值】

    题意:定义最大平均分为 (a1+a2+a3+---+an)/(b1+b2+---+bn),求任意去除k场考试的最大平均成绩 和挑战程序设计上面的最大化平均值的例子一样 判断是否存在x满足条件 (a1+ ...

最新文章

  1. 在Linux下编写Daemon
  2. 2020-09-18
  3. MAC 重置MySQL root 密码
  4. java 模拟ajax上传图片
  5. ssm路径访问不到_ssm整合!!!
  6. 魔兽嘉年华,云信四大码魔与你不见不散
  7. .net 把一个对象赋值给一个参数_Java GC回收算法-判定一个对象是否可以回收
  8. 【从入门到放弃-Java】并发编程-线程安全
  9. 敏捷外包工程系列之三:固定合同(敏捷外包工程,敏捷开发,产品负责人,客户价值)...
  10. win98 支持html5,win98 ghost ghost在WIN98怎么使用
  11. CC2500 使用总结
  12. java poi dataformat_poi的data format可真不怎么样
  13. php源码添加多国语言包,为win7系统添加多国语言包的方法
  14. html canvas 绘制转盘,Canvas绘制转盘
  15. window.open用法详解
  16. 计算机毕业设计Python+uniapp学生考勤系统小程序(小程序+源码+LW)
  17. 长理2019选拔赛1.0
  18. git Incorrect username or password (access token)问题解决
  19. 水清冷冷:PSCC2019/PSCC2020安装教程和学习技巧(附工具)
  20. 在iPhone上如何备份WhatsApp数据

热门文章

  1. 深大计算机与软件学院学生,深圳大学
  2. Docker启动报错“Job for docker.service failed because a configured resource limit was exceeded.
  3. pe制作linux硬盘的镜像文件_用WindowsPE制作的启动U盘或移动硬盘安装cent os 6.2
  4. lotus notes 闪退_win7系统Lotus Notes邮箱闪退的解决方法
  5. springboot将模板生成pdf文件
  6. P3966 [TJOI2013]单词(AC自动机,Trie图)
  7. 织梦网站模板的建站优势
  8. python安全工具开发应用_2019年顶级应用安全工具
  9. SSM框架-Spring(一)
  10. 整型常量是整数类型的数据