P10060 [SNOI2024] 树 V 图
1.P6411 [COCI2008-2009#3] MATRICA2.AT_tenka1_2014_final_d 高橋君3.CF963D Frequency of String4.P4465 [国家集训队] JZPSTR5.P9816 少项式复合幂6.P9817 lmxcslD7.P9821 [ICPC2020 Shanghai R] Sum of Log8.AT_agc034_e Complete Compress9.CF1381D The Majestic Brown Tree Snake10.CF1914F Programming Competition11.P10033 「Cfz Round 3」Sum of Permutation12.AT_abc337_g Tree Inversion
13.P10060 [SNOI2024] 树 V 图
14.P10061 [SNOI2024] 矩阵15.AT_arc170_d Triangle Card Game16.AT_arc170_c Prefix Mex Sequence17.CF1928C Physical Education Lesson18.CF1928D Lonely Mountain Dungeons19.CF1928E Modular Sequence20.CF1634D Finding Zero21.P3756 [CQOI2017] 老C的方块22.P6765 [APIO2020] 交换城市23.P3270 [JLOI2016] 成绩比较24.P5102 [JOI 2016 Final] 领地25.AT_arc148_e ≥ K26.CF1039D You Are Given a Tree27.AT_abc374_f Shipping28.CF2021E3 Digital Village (Extreme Version)29.CF2021D Boss, Thirsty30.CF1876G Clubstep31.P11592 [NordicOI 2024] Chair Game首先想到
判断一下
考虑
并且
于是可以枚举每个点对,时间复杂度
对于所有数据考虑,每个连通块缩起来以后肯定也构成一棵
具体的,记
对于一个
可以先
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=3e3+10,MOD=998244353;
int T,n,k,cur,cnt,x[MAXN],y[MAXN],a[MAXN];
long long t[MAXN],f[MAXN],ans;bool vis[MAXN];
vector <int> v[MAXN],p[MAXN][MAXN];
inline void clear()
{
for(int i=1;i<=n;++i)
{
vis[a[i]]=false;t[i]=f[i]=0,v[i].clear();
for(int j=0;!p[i][j].empty();++j) p[i][j].clear();
}
cnt=ans=0;return ;
}
void init(int x,int fa=0,int dep=0)
{
p[cur][dep].push_back(x);
for(int y:v[x])
if(y!=fa&&a[x]==a[y]) init(y,x,dep+1);
return ;
}
void dfs(int x,int fa=0)
{
for(int y:v[x])
{
if(y==fa) continue;
if(a[x]==a[y]) dfs(y,x);
else
{
dfs(y,x);
for(int depy=0;!p[y][depy].empty();++depy)
for(int j:p[y][depy])
for(int depx=max(depy-1,0);depx<=depy+1;++depx)//这里有个小优化,但是其实没啥必要也没啥用
for(int i:p[x][depx])
if((depx<depy+1||a[x]<a[y])&&(depy<depx+1||a[y]<a[x]))
t[i]=(t[i]+f[j])%MOD;
for(int depx=0;!p[x][depx].empty();++depx)
for(int i:p[x][depx]) f[i]=f[i]*t[i]%MOD,t[i]=0;
}
}
return ;
}
inline void work()
{
clear();cin>>n>>k;
for(int i=1;i<n;++i)
cin>>x[i]>>y[i],
v[x[i]].push_back(y[i]),
v[y[i]].push_back(x[i]);
for(int i=1;i<=n;++i)
cin>>a[i],vis[a[i]]=true,f[i]=1;
for(int i=1;i<=k;++i)
if(!vis[i]) {cout<<"0\n";return ;}
for(int i=1;i<n;++i)
if(a[x[i]]!=a[y[i]]) ++cnt;
if(cnt!=k-1){cout<<"0\n";return ;}
for(int i=1;i<=n;++i) cur=i,init(i);dfs(1);
for(int d=0;!p[1][d].empty();++d)
for(int i:p[1][d]) ans=(ans+f[i])%MOD;
cout<<ans<<'\n';return ;
}
int main()
{
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(0);
cin>>T;while(T--) work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】