P5206 数树 WC2019 Solution
本题包含三个问题:
- 问题 0:已知两棵
个节点的树的形态(两棵树的节点标号均为 至 ),其中第一棵树是红树,第二棵树是蓝树。要给予每个节点一个 中的整数,使得对于任意两个节点 ,如果存在一条路径 同时属于这两棵树,则 必须被给予相同的数。求给予数的方案数。- 存在一条路径同时属于这两棵树的定义见「题目背景」。
- 问题 1:已知蓝树,对于红树的所有
种选择方案,求问题 0 的答案之和。 - 问题 2:对于蓝树的所有
种选择方案,求问题 1 的答案之和。
不妨设边集为
问题0:显然也就是两棵树的公共边保留,答案也就是
问题1:
设
而
即:每个点点权为
定义
容易得到:
初始化
问题2:现在连原树也没了。。。
其实上式也符合,因为两棵树都没有,所以上式的
哦豁,现在就是后式求和怎么玩了。。。
考虑每个连通块,大小为
所以所求:
所以答案为:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int p=998244353;
int n,y,op;
int power(int a,int b){
int res=1;a%=p;b%=(p-1);
while(b){
if(b&1)res=res*a%p;a=a*a%p;b>>=1;
}
return res;
}
namespace Soly1{
void sol(){
if(op==0)cout<<"1";
else if(op==1)cout<<power(n,n-2);
else cout<<power(n,(n-2)<<1);
}
}
namespace Sol0{
#define pr pair<int,int>
#define mk make_pair
map<pr,int>h;
void sol(){
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;if(u>v)swap(u,v);
h[mk(u,v)]=1;
}
int t=0;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;if(u>v)swap(u,v);
t+=h[mk(u,v)];
}
cout<<power(y,n-t);
}
}
namespace Sol1{
int f[N][2],w;
vector<int>e[N];
void dfs(int u,int fa){
f[u][0]=1,f[u][1]=w;
for(auto v:e[u]){
if(v==fa)continue;
dfs(v,u);
int a=f[u][0]*f[v][0]%p+f[u][0]*f[v][1]%p;
int b=f[u][1]*f[v][0]%p+f[u][1]*f[v][1]%p+f[u][0]*f[v][1]%p;
f[u][0]=a%p;
f[u][1]=b%p;
}
}
void sol(){
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;e[u].push_back(v);e[v].push_back(u);
}
w=n*y%p*power(1-y,p-2)%p;
dfs(1,0);
int res=power(1-y,n)*power(n*n,p-2)%p*f[1][1]%p;
res=(res%p+p)%p;
cout<<res<<"\n";
}
}
namespace Sol2{
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!