qoj4885 Triangular Cactus Paths
题意
给出一个环长度最多为 \(3\) 的简单仙人掌图,\(q\) 个询问,每次询问给出 \(s,f,k\),求 \(s\) 到 \(f\) 长度恰好为 \(k\) 的简单路径数量。
思路
仙人掌图显然圆方树,但是因为环长度最多为 \(3\),所以 tarjan 都省了。
询问首先求出 \(s\) 到 \(f\) 的最长路径长度(就是圆方树上的路径长度)\(d\) 和经过的环的数量(即方点数量)\(c\)。
从环上的一个点到另一个点,可以走 \(1\) 步,也可以走 \(2\) 步。
因此为了使得路径长度为 \(k\),我们需要在 \(d-k\) 个环上走一步,其他环上走两步。
显然不同的方案数为 \(\binom{c}{d-k}\),注意判无解。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll fpow(ll x,ll y,ll p){
ll res=1,t=x;
while(y){
if(y&1) res=(res*t)%p;
t=(t*t)%p,y>>=1;
}
return res;
}
const ll md=998244353;
ll fp[200005],inv[200005];
ll C(int x,int y){
return fp[x]*inv[y]%md*inv[x-y]%md;
}
int n,m,tot,dep[400005],cnt[400005],f[400005][25],q;
vector<int> t[400005],t2[400005];
map<pair<int,int>,bool> ct;
bool vis[400005];
void dfs(int x,int fa){
vis[x]=true;
for(int v:t2[x]){
if(v!=fa){
if(vis[v]){
if(ct[{x,v}]) continue;
ct[{x,v}]=ct[{v,x}]=ct[{x,fa}]=ct[{fa,x}]=ct[{v,fa}]=ct[{fa,v}]=true;
tot++;
t[x].push_back(tot);
t[tot].push_back(x);
t[fa].push_back(tot);
t[tot].push_back(fa);
t[v].push_back(tot);
t[tot].push_back(v);
}
else
dfs(v,x);
}
}
}
void dfs2(int x,int fa){
dep[x]=dep[fa]+1;
cnt[x]=cnt[fa]+(x>n);
f[x][0]=fa;
for(int i=1;i<=20;i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int v:t[x])
if(v!=fa) dfs2(v,x);
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--)
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>m;
fp[0]=inv[0]=1;
for(int i=1;i<=200000;i++)
fp[i]=fp[i-1]*i%md,inv[i]=fpow(fp[i],md-2,md);
tot=n;
for(int x,y,i=1;i<=m;i++){
cin>>x>>y;
t2[x].push_back(y);
t2[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=n;i++)
for(int v:t2[i])
if(!ct[{i,v}])
t[i].push_back(v);
dfs2(1,0);
cin>>q;
while(q--){
int x,y,k,l,d,c;
cin>>x>>y>>k;
l=lca(x,y);
d=dep[x]+dep[y]-2*dep[l];
c=cnt[x]+cnt[y]-2*cnt[l]+(l>n);
if(d-k<0||d-k>c) cout<<0<<endl;
else cout<<C(c,d-k)<<endl;
}
return 0;
}

浙公网安备 33010602011771号