Atcoder ABC387F Count Arrays 题解 [ 绿 ] [ 基环树 ] [ 树形 dp ] [ 前缀和优化 ]
Count Arrays:一眼秒的计数题。
思路
显然,把小于等于的条件化为大的向小的连单向边,每个数的入度都是 \(1\),就会形成一个基环树森林。
那么考虑这个环上能填什么数。因为所有数都小于等于他后面的数,所以所有数都只能相等。这就启发我们在基环树上缩点之后再进行计数。
那么当缩完点计数时如何计算呢?有个很简单的 dp,定义 \(dp_{i,j}\) 表示考虑到节点 \(i\),节点 \(i\) 填 \(j\) 的方案数,则很容易能写出转移:
\]
直接转移是 \(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 ] [ 前缀和优化 ]的更多相关文章
- 洛谷 P1453 城市环路 ( 基环树树形dp )
题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...
- HDU6403 Card Game【基环树 + 树形DP】
HDU6403 Card Game 题意: 给出\(N\)张卡片,卡片正反两面都有数字,现在要翻转一些卡片使得所有卡片的正面的值各不相同,问最小翻转次数和最小翻转情况下的不同方案数 \(N\le 10 ...
- 骑士 HYSBZ - 1040(基环树+树形dp)
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...
- BZOJ 1040 骑士 基环树 树形DP
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫 ...
- bzoj 1040: [ZJOI2008]骑士【基环树+树形dp】
没考虑可以连着两个不选--直接染色了 实际上是基环森林,对于每棵基环树,dfs找出一个环边,然后断掉这条边,分别对这条边的两端点做一边treedp,取max加进答案里 treedp是设f[u]为选u点 ...
- BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)
<题目链接> 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...
- 4.13 省选模拟赛 树 树形dp 卷积 NTT优化dp.
考试的时候 看到概率 看到期望我就怂 推了一波矩阵树推自闭了 发现 边权点权的什么也不是. 想到了树形dp 维护所有边的断开情况 然后发现数联通块的和再k次方过于困难. 这个时候 应该仔细观察一下 和 ...
- BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】
题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...
- day 2 下午 骑士 基环树+树形DP
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc ...
- 51nod 1353 树 | 树形DP经典题!
51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...
随机推荐
- java集合【10】——— LinkedList源码解析
1.LinkedList介绍 我们除了最最常用的ArrayList之外,还有LinkedList,这到底是什么东西?从LinkedList官方文档,我们可以了解到,它其实是实现了List和Queue的 ...
- Newstar CTF 2023 week2 pwn
1.ret2libc 发现存在pop rdi 观察main函数,可以利用puts函数泄露libc from pwn import * from LibcSearcher import * contex ...
- vue使用docxtemplater导出word
安装 // 安装 docxtemplater npm install docxtemplater pizzip --save // 安装 jszip-utils npm install jszip-u ...
- mysql 创建字段createtime 自动添加时间
1. 创建createtime字段 类型选为timestamp 2. 添加默认值 CURRENT_TIMESTAMP
- 中电资讯-乘风破浪数字经济,银行如何Hold数据?
近期各类规划密集发布人行金融科技发展规划发布 金融标准化"十四五"规划发布 "十四五"信息化规划发布 -- 和数据应用有关的各项政策密集出炉 数字经济发展中如何 ...
- PM的正交解调法
1.PM的模拟调制过程 PM信号是一种相位调制信号,其携带的信息保存在其信号的相位中,通过改变载波的相位来实现基带数据的传输. 其函数表达式如下: \[s(t) = A*cos(w_c*t + K ...
- HarmonyOS Next 入门实战 - 关系型数据库、smartdb
SQLite数据库 HarmonyOS的关系型数据库基于SQLite 导入模块 import { relationalStore } from '@kit.ArkData'; 实现步骤: 获取RdbS ...
- 解决File "<input>", line 1 pip install XXXX ^ SyntaxError: invalid syntax
首先退出python exit() 打开cmd里直接输入(不要进python) pip install XXX
- Qt/C++通用跨平台Onvif工具/支持海康大华宇视华为天地伟业等/云台控制/预置位管理/工程调试利器
一.前言 在安防视频监控行业,Onvif作为国际标准,几乎主要的厂商都支持,不仅包含了国内的厂商,也包括主要的国际厂商,由于有了这个标准的存在,使得不同设备不同安防平台之间,能够接入各个厂家的硬件设备 ...
- Qt编写的项目作品32-定制化安装包工具(雨田哥作品)
一.功能特点 纯Qt编写,跨平台. 支持自定义安装目录等. 安装和卸载界面可自定义. 一键式脚本build.bat,生成安装包EXE. 兼容XP系统. 支持配置文件填充安装包信息. 指定应用程序中文名 ...