Count Arrays:一眼秒的计数题。

思路

显然,把小于等于的条件化为大的向小的连单向边,每个数的入度都是 \(1\),就会形成一个基环树森林。

那么考虑这个环上能填什么数。因为所有数都小于等于他后面的数,所以所有数都只能相等。这就启发我们在基环树上缩点之后再进行计数。

那么当缩完点计数时如何计算呢?有个很简单的 dp,定义 \(dp_{i,j}\) 表示考虑到节点 \(i\),节点 \(i\) 填 \(j\) 的方案数,则很容易能写出转移:

\[dp_{i,j}=\prod_{k=1}^{\left|son_i\right|}(\sum_{a=1}^{j}dp_{son_{i,k},a})
\]

直接转移是 \(O(nm^2)\) 的,前缀和优化即可做到 \(O(nm)\)。

答案计算时将所有基环树的答案乘起来即可。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
using pii=pair<int,pi>;
const ll mod=998244353;
int n,m,a[10005];
int dfn[10005],low[10005],stk[10005],cnt=0,tp=0,scc[10005],tot=0;
bitset<10005>instk,vis,rd;
vector<int>g[10005],tr[10005];
ll ans=1,dp[3005][3005],f[3005][3005];
void tarjan(int u)
{
dfn[u]=low[u]=++tot;
instk[u]=1,stk[++tp]=u;
for(auto v:g[u])
{
if(dfn[v]==0)
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instk[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
int now;
cnt++;
do{
now=stk[tp--];
instk[now]=0;
scc[now]=cnt;
}while(now!=u);
}
}
void dfs(int u)
{
for(int i=1;i<=m;i++)dp[u][i]=1;
for(auto v:tr[u])
{
dfs(v);
for(int i=1;i<=m;i++)
{
dp[u][i]=(dp[u][i]*f[v][i])%mod;
}
}
for(int i=1;i<=m;i++)f[u][i]=(f[u][i-1]+dp[u][i])%mod;
}
int main()
{
//freopen("sample.in","r",stdin);
//freopen("sample.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
g[a[i]].pb(i);
}
for(int i=1;i<=n;i++)if(dfn[i]==0)tarjan(i);
for(int i=1;i<=n;i++)
{
int fu=scc[i];
for(auto v:g[i])
{
int fv=scc[v];
if(fu!=fv)
{
tr[fu].pb(fv);
rd[fv]=1;
}
}
}
for(int i=1;i<=cnt;i++)
{
if(rd[i]==0)
{
dfs(i);
ans=(ans*f[i][m])%mod;
}
}
cout<<ans;
return 0;
}

Atcoder ABC387F Count Arrays 题解 [ 绿 ] [ 基环树 ] [ 树形 dp ] [ 前缀和优化 ]的更多相关文章

  1. 洛谷 P1453 城市环路 ( 基环树树形dp )

    题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...

  2. HDU6403 Card Game【基环树 + 树形DP】

    HDU6403 Card Game 题意: 给出\(N\)张卡片,卡片正反两面都有数字,现在要翻转一些卡片使得所有卡片的正面的值各不相同,问最小翻转次数和最小翻转情况下的不同方案数 \(N\le 10 ...

  3. 骑士 HYSBZ - 1040(基环树+树形dp)

    Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...

  4. BZOJ 1040 骑士 基环树 树形DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫 ...

  5. bzoj 1040: [ZJOI2008]骑士【基环树+树形dp】

    没考虑可以连着两个不选--直接染色了 实际上是基环森林,对于每棵基环树,dfs找出一个环边,然后断掉这条边,分别对这条边的两端点做一边treedp,取max加进答案里 treedp是设f[u]为选u点 ...

  6. BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)

    <题目链接> 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...

  7. 4.13 省选模拟赛 树 树形dp 卷积 NTT优化dp.

    考试的时候 看到概率 看到期望我就怂 推了一波矩阵树推自闭了 发现 边权点权的什么也不是. 想到了树形dp 维护所有边的断开情况 然后发现数联通块的和再k次方过于困难. 这个时候 应该仔细观察一下 和 ...

  8. BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】

    题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...

  9. day 2 下午 骑士 基环树+树形DP

    #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc ...

  10. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

随机推荐

  1. element table 合并同类项并输出后台返回数据

    table的样式如下 后台返回的数据格式是按照横着来的,因为表头是经过处理的,而且是作为独立出来的数据返给前端的,所以当我们进行数据填充的时候需要用到后台返回的完整的数据,要想一一对应的话,我们需要进 ...

  2. ZCMU-1179

    我的错误: 明知道是大数问题但不是不想写数组或者字符串的结构. 思路 网上查阅后发现可以使用JAVA的大数类型做. 若不使用JAVA则就是整型数组或者字符串的情况. 将a^b结果放在数组当中,实时更新 ...

  3. FileSaver 文件导出

    1.前言 本节主要讲述如何将后台返回的JSON以文件的形式保存到本地 官方文档 兼容性(转载) Browser Constructs as Filenames Max Blob Size Depend ...

  4. HTML img标签

    1.基本用法 <img src="kof5.jpg" alt="特瑞"> src属性为图片的链接地址,如果图片加载失败,代替图片的就是alt属性设置 ...

  5. uniapp+django 新手学习步骤记录 (1)

    第一次学习uniapp和django,找了一个入门教程遇到坑,记录一下. 1.Django项目和uni-app项目的创建及项目文件讲解_慕容星言的博客-CSDN博客 (1)注意同时安装了python2 ...

  6. 树莓派4B 关闭休眠,关闭屏保

    1.安装 sudo apt install xscreensaver 2.打开xscreensaver sudo xscreensaver-demo 3.设置 参考:https://zhuanlan. ...

  7. Redis应用—3.在购物车里的应用

    大纲 1.社区电商购物车的读多写多场景分析 2.购物车的复杂缓存与异步落库(Sorted Set + Hash -> hPut + zadd) 3.购物车异步落库与完整加入流程(缓存雪崩 + M ...

  8. Flutter自动生成安卓和IOS图标

    flutter_launcher_icons 用这个库自动生成 首先添加依赖 dev_dependencies: flutter_launcher_icons: flutter_icons: andr ...

  9. WSLg 中文输入法 fcitx5

    随着 Win11 22H2 和 WSLg 的推出,很多开启输入法的教程都过时了.记录一下最新实践: WSL 安装 Ubuntu 后,安装中文语言 sudo /usr/bin/gnome-languag ...

  10. 【WEB前端】【JQuery】搜索li标签的内容

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...