烈阳

· · 题解

upd:

简要题意

给定 k1\sim n 的置换 p_1,p_2,\cdots,p_k,对于这些置换相互复合生成的置换群 S=<p_1,p_2,\cdots,p_k> ,求 \dfrac{\sum\limits_{q\in S}\sigma(q)}{|S|} 关于一个大质数的模数。

满足 1\le n\le 3000k\le 3000

若干关键观察

考虑优化

考虑简要分析(口胡)正确性

:::success[Code(略去缺省源)]

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
struct Mod{
    ll v,p;
    constexpr Mod(int x){
        p=x;
        v=((__int128)(1)<<64)/p;
    }
    inline int operator()(ll x)const{
        return x-((__int128)(x)*v>>64)*p;
    }
};
const Mod bar(mod);
int n,k,ans,tot,id[3005][3005];
vector<int>p[3005];
int fa[9000005],w[9000005],siz[9000005],inv[9000005];
int find(int x){
    if(fa[x]==x)return x;
    else return fa[x]=find(fa[x]);
}
void uni(int x,int y){
    x=find(x);y=find(y);
    if(x==y)return;
    if(w[x]>w[y])swap(x,y);
    fa[x]=y;
    w[y]+=w[x];
    siz[y]+=siz[x];
}
mt19937 rd(20260616);
signed main()
{
    read(n,k);
    for(int i=1;i<=k;i++){
        p[i].resize(n+1);
        for(int j=1;j<=n;j++)read(p[i][j]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            id[i][j]=++tot;
            fa[tot]=tot;
            siz[tot]=1;
            w[tot]=(i>j);
        }
    }
    auto upd=[&](vector<int>pr){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int u=id[i][j],v=id[pr[i]][pr[j]];
                uni(u,v);
            }
        }
    };
    int ttt=30;
    while(ttt--){
        shuffle(p+1,p+k+1,rd);
        vector<int>x(n+1),y(n+1);
        for(int i=1;i<=n;i++)x[i]=i;
        for(int i=1;i<=k;i++){
            if(rd()%2){
                for(int j=1;j<=n;j++)y[j]=x[p[i][j]];
                x.swap(y);
            }
        }
        upd(x);
    }
    inv[1]=1;
    for(int i=2;i<=n*n;i++)inv[i]=bar((ll)(mod-mod/i)*inv[mod%i]);
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int p=find(id[i][j]);
            ans+=bar((ll)w[p]*inv[siz[p]]);
            ans=ans>=mod?ans-mod:ans;
        }
    }
    print(ans,'\n');
    return 0;
}

:::