Loading

UOJ#75智商锁

题意:给定一个数\(k\),求是否能有一个节点数\(n\)满足\((n≤100)\)的图,使得这个图的生成树种类数模\(998244353\)后等于\(k\)

题解:随机化\(p\)个节点数为\(d\)的图,跑\(p\)遍矩阵树定理,

\(Cayley\)定理完全图的生成树有\(n^{n-2}\)棵。\(p<<n^{n-2}\)个图的生成树个数可以认为在\([0,n^{n-2}]\)内均匀分布。于是有:四个图的生成树种类相乘包括\(p^4\)个数,包括\([0,1e9]\)内的某个数\(t\)的概率是\(K=1-(1-10^{-9})^{p^4}\)
包括\([0,1e9]\)所有数的概率\(K^{10^9}\)
\(p\)\(1000\)\(n\)\(12\)可以使得概率非常接近\(1\).

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod (ll)(998244353)
#define int ll
int t;
int f[maxn];
bool bian[(int)(1e3+1)][15][15];
struct matrix{
    ll ma[15][15];
    void pre(){memset(ma,0,sizeof(ma));}
}du;
ll x1,y;
void exgcd(ll a,ll b){
    if(!b){x1=1;y=0;return;}
    exgcd(b,a%b);
    ll tmp=x1;x1=y;y=tmp-a/b*y;
}
void gauss(int biao){
    ll ans=1;
    int n=11;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            while(du.ma[j][i]){
                ll tmp=du.ma[i][i]/du.ma[j][i];
                for(int k=i;k<=n;k++) du.ma[i][k]=((du.ma[i][k]-tmp*du.ma[j][k]%mod)+mod)%mod;
                std::swap(du.ma[i],du.ma[j]);
                ans=-ans;
            }
        }
        ans=ans*du.ma[i][i]%mod;
    }
    f[biao]=(ans%mod+mod)%mod;
}
void sheng(int biao){
    for(int i=1;i<=12;i++){
        for(int j=i+1;j<=12;j++){
            if(i==j) continue;
            bian[biao][i][j]=(rand()%10>=8)?0:1;
            bian[biao][j][i]=bian[biao][i][j];
        }
    }
    du.pre();
    for(int i=1;i<=12;i++){
        for(int j=1;j<=i;j++){
            if(bian[biao][i][j]){
                du.ma[i][j]--,du.ma[j][i]--;
                du.ma[i][i]++,du.ma[j][j]++;////
            }
        }
    }
}
map<ll,pii> k1;
map<ll,ll> k2;
int mp[(int)(1e3+1)][(int)(1e3+1)];
ll ksm(ll a,ll ci){
    ll ans1=1;
    while(ci>0){
        if(ci&1) ans1=ans1*a%mod;
        ci/=2;a=a*a%mod;
    }
    return ans1%mod;
}
signed main(){
    for(int i=1;i<=800;i++){
        sheng(i);
        gauss(i);
    }
    for(int i=1;i<=800;i++){
        for(int j=1;j<=800;j++){
            ll now2=f[i]*f[j]%mod;
            k1[f[i]*f[j]%mod]=make_pair(i,j);
            ll now3=ksm(now2,mod-2);
            k2[now2]=now3;
        }
    }
    cin>>t;
    while(t--){
        int k;cin>>k;
        if(k==0){cout<<48<<' '<<0<<endl;continue;}
        bool findf=0;
        int now[4];
        for(map<int,pii>::iterator it=k1.begin();it!=k1.end();it++){
            int now1=(*it).first;
            int now2=k2[now1]%mod*k%mod;
            if(k1.find(now2)==k1.end()) continue;
            findf=1;
            now[0]=k1[now1].first,now[1]=k1[now1].second;
            now[2]=k1[now2].first,now[3]=k1[now2].second;
            break;
        }
        if(!findf){cout<<"QwQ\n";continue;}
        else{
            vector<pii> k3;
            cout<<48<<' ';
            int m=0;
            for(int i=0;i<4;i++){
                int now1=now[i];
                for(int j=1;j<=12;j++){
                    for(int k=1;k<=j;k++) if(bian[now1][j][k]){m++;k3.push_back(make_pair(j+12*i,k+12*i));}
                }
            }
            cout<<m+3<<endl;
            cout<<1<<' '<<13<<endl<<1<<' '<<25<<endl<<1<<' '<<37<<endl;
            for(int i=0;i<k3.size();i++){
                cout<<k3[i].first<<' '<<k3[i].second<<endl;
            }
        }
    }
}
posted @ 2021-07-19 20:45  14long  阅读(66)  评论(0)    收藏  举报