[计蒜之道2019 复赛 A]外教 Michale 变身大熊猫

Online Judge2019计蒜之道 复赛 A

Label:LIS+线段树、树状数组+快速幂(模逆元)

题目描述

题解:

pre.关于本题中模逆元的提示:

对于一个质数mod,q的模逆元是\(q^{mod-2}\)。也就是说对于本题,平时一般用形如\(G=\frac{p}{q}\)的分式表示概率,现在,我们利用模逆元来表示这个概率,即\(G=p*q^{mod-2}\)。

那这道题里\(mod=998244353\)是个质数,那就可以利用上面的提示\(G=p*q^{mod-2}\),很明显要用到快速幂,而这个\(q\)就是LIS的个数,那我们只要求每个位置对应的p即可。

①.70%数据的\(O(N^2)\)做法:

想到LIS的O(NlogN)做法——用树状数组或线段树维护前缀最小值优化一下dp。然后可以求出最大上升子序列的长度mal ,接着分别从左到右,再从右到左求一下每个点会在几条LIS上,然后左右的方案数乘一下就是p了。预处理很明显要先离散化一下。离线赛时的70分代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N=1e5+10;
const int mod=998244353;
int r[N],l[N];
int qsm(int x,int b){
int res=1;
while(b){
if(b&1)res=1LL*res*x%mod;
x=1LL*x*x%mod;
b>>=1;
}
return res;
}
int B[N];
int n,num,a[N],b[N],dp[N];
int lowbit(int x){return x&-x;}
void update(int x,int d){
while(x<=num)B[x]=max(B[x],d),x+=lowbit(x);
}
int query(int x){
int res=0;
while(x)res=max(res,B[x]),x-=lowbit(x);
return res;
}
int cnt[N],all;
signed main(){
// freopen("lis.in","r",stdin),freopen("lis.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
num=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
int mal=0;
for(int i=1;i<=n;i++){
int now=query(a[i]-1);
dp[i]=now+1;
if(dp[i]>mal)mal=dp[i];
update(a[i],dp[i]);
}
a[0]=0,dp[0]=0,l[0]=1;
a[n+1]=num+1,dp[n+1]=mal+1,r[n+1]=1;n++;
for(int i=0;i<=n;i++){
for(int j=i+1;j<=n;j++){
if((dp[j]!=dp[i]+1)||a[j]<=a[i])continue;
l[j]=(l[j]+l[i])%mod;
}
}
for(int i=n;i>=0;i--){
for(int j=i-1;j>=0;j--){
if((dp[j]!=dp[i]-1)||a[j]>=a[i])continue;
r[j]=(r[j]+r[i])%mod;
}
}
int all=l[0]*r[0]%mod,q=qsm(all,mod-2);
for(int i=1;i<n;i++)printf("%lld ",r[i]*l[i]%mod*q%mod);
}

②.\(O(NlogN)\)正解

上面的代码也可以优化,但是我们可以直接在求LIS时候维护方案数。

也是一样的思路,从左到右扫一遍,再从右到左扫一遍,然后乘一下得到方案数。然后下面代码利用树状数组维护到目前为止,以离散化后的数字i结尾的LIS最长为\(c[i]\),以及,以其结尾的LIS这么长有\(ti[i]\)条。

由于一次从左到右,一次从右到左,所以打两组树状数组。大致思路同上面的代码:

//快速幂->模逆元,树状数组、线段树维护
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N=1e5+10;
const int mod=998244353;
int num,a[N],b[N];
int dp[N],li[N],ans[N];
int presum,c[N],ti[N];
int add1(int x,int mal,int d){
while(x<=num){
if(mal>c[x])c[x]=mal,ti[x]=d;
else if(mal==c[x])ti[x]=(ti[x]+d)%mod;
x+=x&(-x);
}
}
int sum1(int x){
int res=0;
while(x){
if(res<c[x])res=c[x],presum=ti[x];
else if(res==c[x])presum+=ti[x];
x-=x&(-x);
}
return res;
}
void add2(int x,int mal,int d){
while(x){
if(mal>c[x])c[x]=mal,ti[x]=d;
else if(mal==c[x])ti[x]=(ti[x]+d)%mod;
x-=x&(-x);
}
}
int sum2(int x){
int res=0;
while(x<=num){
if(res<c[x])res=c[x],presum=ti[x];
else if(res==c[x])presum+=ti[x];
x+=x&(-x);
}
return res;
}
int ksm(int x,int b){
int res=1;
while(b){
if(b&1)res=res*x%mod;
x=x*x%mod;
b>>=1;
}
return res;
}
signed main(){
int n;scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
num=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
int lis=0;
for(int i=1;i<=n;i++){
presum=0;
int now=sum1(a[i]-1);presum%=mod;
dp[i]=now+1;
lis=max(lis,dp[i]);
if(dp[i]==1)li[i]=1;
else li[i]=presum;
add1(a[i],dp[i],li[i]);
}
memset(c,0,sizeof(c));
memset(ti,0,sizeof(ti));
int tot=0;
for(int i=n;i>=1;i--){
presum=0;
int now=sum2(a[i]+1);presum%=mod;
int ri=(now==0?1:presum);
if((dp[i]+now)==lis)ans[i]=li[i]*ri%mod;
if(dp[i]==lis)tot=(tot+ans[i])%mod;
add2(a[i],now+1,ri);
}
int q=ksm(tot,mod-2);
for(int i=1;i<=n;i++)printf("%lld ",ans[i]*q%mod);
return 0;
}

[计蒜之道2019 复赛 A]外教 Michale 变身大熊猫的更多相关文章

  1. 2018 计蒜之道复赛 贝壳找房魔法师顾问(并查集+dfs判环)

    贝壳找房在遥远的传奇境外,找到了一个强大的魔法师顾问.他有 22 串数量相同的法力水晶,每个法力水晶可能有不同的颜色.为了方便起见,可以将每串法力水晶视为一个长度不大于 10^5105,字符集不大于  ...

  2. 计蒜之道 百度AI小课堂-上升子序列

    计蒜之道 百度AI小课堂-上升子序列 题目描述 给一个长度为 \(n\) 的数组 \(a\) .试将其划分为两个严格上升子序列,并使其长度差最小. 输入格式 输入包含多组数据. 数据的第一行为一个正整 ...

  3. 2019 计蒜之道 复赛 E. 撑起信息安全“保护伞” (贪心,构造,规律)

    为了给全球小学员打起信息安全"保护伞",VIPKID 还建立了一套立体化的安全防御体系,7 \times 247×24 小时持续安全监控与应急响应等多项联动,具备业界最高级别的数据 ...

  4. 2019 计蒜之道 复赛 B. 个性化评测系统 (模拟,实现,暴搜)

    24.02% 1000ms 262144K "因材施教"的教育方式自古有之,互联网时代,要实现真正意义上的个性化教育,离不开大数据技术的扶持.VIPKID 英语 2020 多万学员 ...

  5. 2019 计蒜之道 复赛 D. “星云系统”(单调栈)

    VIPKID 是在线少儿英语教育平台,网络稳定是在线教育课程质量的红线,VIPKID 为此推出了全球最稳定的教育网络系统 -- "星云系统".星云系统目前建立了覆盖全球 3535 ...

  6. 2016计蒜之道复赛 百度地图的实时路况 floyd+cdq分治

    链接:https://nanti.jisuanke.com/t/11217 奉上官方题解: 枚举 d(x , y , z) 中的 y,把 y 从这个图中删去,再求这时的全源最短路即可,使用 Floyd ...

  7. 2016计蒜之道复赛 菜鸟物流的运输网络 网络流EK

    题源:https://nanti.jisuanke.com/t/11215 分析:这题是一个比较经典的网络流模型.把中间节点当做源,两端节点当做汇,对节点进行拆点,做一个流量为 22 的流即可. 吐槽 ...

  8. 2016计蒜之道复赛B题:联想专卖店促销

    题解 思路: 二分答案,设我们要check的值为x. 注意到每一个礼包都有,一个U盘,一个鼠标. 剩余的,分别为一个机械键盘,一个U盘,一个鼠标. 当礼包数目为x时,我们至多可以提供a-x个普通,b- ...

  9. 2016计蒜之道复赛 百度地图的实时路况(Floyd 分治)

    题意 题目链接 Sol 首先一个结论:floyd算法的正确性与最外层\(k\)的顺序无关(只要保证是排列即可) 我大概想到一种证明方式就是把最短路树上的链拿出来,不论怎样枚举都会合并其中的两段,所以正 ...

随机推荐

  1. maven创建archetyp一直显示runing

    在maven的五分钟入门里面,有这样一个命令: mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -Darc ...

  2. mysql 查询当前日期

    1.本年份 SELECT DATE_FORMAT(NOW(), '%Y'); 2.本月份(显示数字) SELECT DATE_FORMAT(NOW(), '%m'); 3.本月份(显示英文) SELE ...

  3. thinkphp import标签

    传统方式的导入外部JS和CSS文件的方法是直接在模板文件使用: 直线电机哪家好 <script type='text/javascript' src='/Public/Js/Util/Array ...

  4. csps模拟93序列,二叉搜索树,走路题解

    题面: 模拟93考得并不理想,二维偏序没看出来,然而看出来了也不会打 序列: 对a,b数列求前缀和,那么题意转化为了满足$suma[i]>=suma[j]$且$sumb[i]>=sumb[ ...

  5. 「STL」bitset正传

    前言 之前一些需要转二进制来解决的题目我看到很多大佬用了bitset. 然而我并不会这东西.看上去很高级的样子…… 改题改累了来学习一下233. 正文 一.bitset的构造 bitset有三种构造方 ...

  6. CF1086F Forest Fires

    CF1086F Forest Fires 有点意思的题目 直接统计每个格子的val是非常难办的.很难知道每秒新出来多少个格子 设$F[i]$表示,前i时刻覆盖的格子的数量 则,$ans=\sum_{i ...

  7. 《DSP using MATLAB》Problem 8.35

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  8. 安装MySQL出现的this application

    1,https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=1385 2,安装Windows 图像组件 (WIC)以及NET Fra ...

  9. JVM系列(三)— Java内存模型

    我们已经了解了Java虚拟机的运行时数据区,垃圾收集相关知识,接下来学习虚拟机非常重要的部分 这就是Java内存模型与线程(第12章),这一篇,将主要讲讲内存模型 了解Java内存模型之前,先了解下计 ...

  10. NEERC 2015 Adjustment Office /// oj25993

    题目大意: 输入n,q: 矩阵大小为n*n 每个位置的值为该位置的行数+列数 接下来q行 “R m”表示输出第m行的总和并整行消去 “C m”表示输出第m列的总和并整列消去 Sample Input ...