[计蒜之道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. CSIC_716_20191111【函数对象、名称空间、作用域、global 和nonlocal】

    函数名是可以被引用,传递的是函数的内存地址.函数名赋值给变量后,只需要在变量后加上括号即可调用函数. 名称空间 内置名称空间:在python解释器中提前定义完的名字 全局名称空间:if.while.f ...

  2. ac与ap同步分析

    1 ApStatusRequest : ap把自己的状态发过来做请求  就相当于自我介绍 网关上抓包 : tcpdump -ni br-lan tcp port 8090   -Avv / -w po ...

  3. 校园商铺-4店铺注册功能模块-3thumbnailator图片处理和封装Util

    1. 初步使用thumbnailator 1.1 下载依赖 <!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator - ...

  4. 請問各位大大,我要將listview顯示的縮圖加入到listview2,請問該如何做呢

    請問各位大大,我要將listview顯示的縮圖加入到listview2,請問該如何做呢?下面的function可以將listview的縮圖加到listview2但是全都顯示listview1第一張的圖 ...

  5. iOS开发UITableView随笔

    1.设置cell的间隔 - (void)setFrame:(CGRect)frame{ frame.size.height -=; [super setFrame:frame]; } 2.刷新row或 ...

  6. Maven父子工程配置文件详解

    项目骨架搭建成功之后. 因为父工程管理子工程.子工程相当于继承于子工程,所以子工程可以调用父工程里面的东西.那么就可以将jar包对应的配置文件书写到父工程的pom.xml文件中,注意:父工程的打包方式 ...

  7. 用原生js封装轮播图

    原生js封装轮播图 对于初学js的同学来说,轮播图还是一个难点,尤其是原生js封装轮播图代码,下面是我之前做的一个轮播图项目中封装好的一些代码,有需要的同学可以看一下,有什么不懂的可以看注释,注释看不 ...

  8. ASP.NET自定义Validform的datatype

    1.定义 <script type="text/javascript"> $(function () { $("#aa").Validform({ ...

  9. UNIT对话系统(杂记)

    单轮对话指标: 召回率=机器人能回答的问题数/问题总数 准确率=机器人正确回答的问题数/问题总数 问题解决率=机器成功解决的问题数/问题总数 多轮对话指标: 任务完成率=成功结束的多轮会话数/多轮会话 ...

  10. <Python基础>python是如何进行内存管理的

    .Python 是如何进行内存管理的?答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制⒈对象的引用计数机制Python 内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用 ...