目前計蒜客上面AC數量還是0,我也懶得交,估計CF Gym裏面也該有這道,懶得找了。
題解:
今天的簽到題。
把for循環換個思路考慮:
for var in range ( l , r ):
冷靜一想不難發現等價於:
for var in range ( 1 , n ):
if(l <= var && var <= r)
於是實際上要求的就是有多少變量取值滿足題意給的不等式鏈。
首先建立有向邊,然後縮點,由於圖太小了我就懶得寫tarjan,直接用Floyd,顯然同一個SCC裏面的變量取值要一樣,不同的構成一個DAG。
複雜度中 的次數顯然就是 的點數。
考慮一下係數表示的東西是什麼,這裏比較抽象,表示的應該是所有可能的取值情況佔了所有情況的幾分之幾。
漸進意義下強行讓所有SCC不同不會改變答案,於是係數就是 ,考慮所有點的大小關係還是挺顯然的。
求拓撲序個數顯然直接狀壓DP即可。
代碼:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int N=21;
int n;
bool g[N][N];
int rt[N],bel[N];
ll dp[(1<<N)|7];
int ct=0,mp[1000];
int gid(int x){
return (mp[x]?mp[x]:mp[x]=++ct)-1;
}
void Main(){
std::ios::sync_with_stdio(false);
int m;std::cin>>m;
for(int re i=1;i<m;++i){
std::string tmp,v,l,r;
std::cin>>tmp>>v>>tmp>>l>>r;
int a=gid(v[0]),b=l[6],c=r[0];
if(b!='1')g[gid(b)][a]=true;
if(c!='n')g[a][gid(c)]=true;
}
for(int re k=0;k<ct;++k)
for(int re i=0;i<ct;++i)
for(int re j=0;j<ct;++j)
g[i][j]|=g[i][k]&g[k][j];
for(int re i=0;i<ct;++i){
bool tos=false;
for(int re j=0;j<i&&!tos;++j)
tos|=g[i][j]&&g[j][i];
if(!tos)rt[n++]=i;
}
for(int re i=0;i<n;++i)
for(int re j=0;j<n;++j){
if(g[rt[i]][rt[j]]&&i!=j)
bel[i]|=1<<j;
}
dp[0]=1;
for(int re s=0;s<(1<<n);++s)
for(int re i=0;i<n;++i)
if(!(s&(1<<i))&&(bel[i]|s)==s)
dp[s|(1<<i)]+=dp[s];
ll up=dp[(1<<n)-1],dn=1;
for(int re i=1;i<=n;++i)dn*=i;
ll g=std::__gcd(up,dn);
cout<<n<<" "<<up/g<<"/"<<dn/g<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("fygon.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
freopen("fygon.in","r",stdin);
freopen("fygon.out","w",stdout);
#endif
#endif
}signed main(){file();Main();return 0;}