首页 > 其他分享 >P10353 [PA2024] Grupa permutacji 题解

P10353 [PA2024] Grupa permutacji 题解

时间:2024-10-16 20:21:17浏览次数:1  
标签:permutacji 连通 int 题解 perm Grupa maxn pi mod

神秘!在这些排列生成的置换群 \(G\) 里,若 \(\exists \pi \in G\) 使得 \(\pi_i=k,\pi_j=l\),则所有这些 \((k,l)\) 被同样数量的 \(\pi\in G\) 通过前述方法得出。

证明:设 \(\pi(i,j)=(k,l),\pi'(i,j)=(k',l')\)(意义前述),则 \(\pi^{-1}\circ \pi'(k,l)=(k',l')\),这表明 \((k',l')\) 的方案数不少于 \((k,l)\),因为每个 \((k,l)\) 方案可以复合 \(\pi^{-1}\circ \pi'\) 得到 \((k',l')\) 方案。对于所有二元组对这都成立,因此所有方案数相等。

因此我只需统计连通信息,尝试选择更少的能产生同样连通性的排列。考察一个连通块内部,就是需要 \(S_n\) 的更少联通排列。考虑随机在 \(S_n\) 里选排列,其生成的循环如果不是大小全部相同(可能性极小),那么跨循环之间的点对已经连通;而循环最大大小很有可能是 \(n\) 的\(0.6\sim 0.7\) 倍。因此我大概只需要 \(\log\) 次选择可以连通所有点(在说啥,,)。

因此我只需随机大约 \(\log\) 次,每次做多次随机决定是否复合某个给定排列即可。把这些拿出来求连通块即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e3+5,lim=24,mod=1e9+7;
int ans=0,n,k,b[maxn],vis[maxn*maxn];
struct perm{int p[maxn];}S[maxn];
inline perm operator ^(const perm &A,const perm &B){
	perm C;
	for(int i=1;i<=n;i++)C.p[i]=A.p[B.p[i]];
	return C;
}
mt19937 rng(time(0));
int Fa[maxn*maxn],A[maxn*maxn],B[maxn*maxn],inv[maxn*maxn*2];
int id(int i,int j){return (i-1)*n+j;}
int Find(int x){return x==Fa[x]?x:Fa[x]=Find(Fa[x]);}
int qp(int a,int b){
	if(b==0)return 1;
	int T=qp(a,b>>1);T=T*T%mod;
	if(b&1)T=T*a%mod;
	return T;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<=k;i++)for(int j=1;j<=n;j++)cin>>S[i].p[j];
	for(int i=1;i<=n*n;i++)Fa[i]=i;
	for(int i=1;i<=lim;i++){
		perm I;for(int j=1;j<=n;j++)I.p[j]=j;
		for(int j=1;j<=k;j++)if(rng()&1)I=I^S[j];
		for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)Fa[Find(id(i,j))]=Find(id(I.p[i],I.p[j]));	
	}
	for(int i=1;i<=n*n*2;i++)inv[i]=qp(i,mod-2);
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)A[Find(id(i,j))]+=i<j,B[Find(id(i,j))]+=i>j;
	for(int i=1;i<=n*n;i++)if(Find(i)==i)(ans+=(A[i]*B[i])%mod*inv[A[i]+B[i]])%=mod;
	cout<<ans<<endl;
	return 0;
}

标签:permutacji,连通,int,题解,perm,Grupa,maxn,pi,mod
From: https://www.cnblogs.com/british-union/p/18470824

相关文章

  • [题解]P3952 [NOIP2017 提高组] 时间复杂度
    P3952[NOIP2017提高组]时间复杂度我们把循环的嵌套关系看做树形结构,梳理一下\(3\)种情况:直接跳过当前子树:\(x,y\in\mathbb{N}\),且\(x>y\)。\(x=\tt{"n"},y\in\mathbb{N}\)。不跳过,并在处理完所有子节点后追加\(n\)的时间复杂度:\(x\in\mathbb{N},y=\tt{"n"}\)。......
  • 【题解】[2023 合肥蜀山初中] 旅行(travel)
    题目传送门题目大意有一个\(n\)个点\(m\)条边的有向图组成的城市,每条边可以是骑行边或公共交通边,公共交通边只能走一条,边是从\(u_i\)到\(v_i\)的有向边,需要花费\(time_i\)的时间,求\(1\)到其他点的最短路径。思路分析有一个很巧妙的思路叫分层图,它的思路是因为只能......
  • Excel DLL丢失?Excel DLL文件下载指南及常见问题解决方案
    当您在使用MicrosoftExcel时遇到提示DLL文件丢失或损坏的情况,这可能会影响软件的正常运行。为了帮助您解决这一问题,本文提供了ExcelDLL文件的下载指南,并针对常见问题给出了解决方案。一、ExcelDLL文件下载指南确定缺失的DLL文件:首先,您需要确定是哪个DLL文件丢失或损坏......
  • 数据结构1系列题解前瞻
    A.线段树分裂算法:线段树、(平衡树?)板子题,不多做评价。但是开发空间很大,我的写法在洛谷题解上没找到,导致当时想贺题解没贺成。B.三元上升子序列算法:线段树、树状数组、分块、(CDQ分治?)二维偏序板子,开发空间极大,想怎么写就怎么写。C.STEP算法:线段树、分块线段树维护子区间信......
  • P1941 NOIP2014 提高组 飞扬的小鸟 题解
    P1941NOIP2014提高组飞扬的小鸟分析背包经典演变问题玩得挺花。设\(f[i][j]\)表示到达\((i,j)\)的时候的最小点击次数。题目中对于每一个\(i\)有两种处理:点击与不点击(重点:点击可以叠加)。所以,对于点击,我们可以像完全背包一样转移,而不点击就按照01背包转移。对于管......
  • [NOI2020] 美食家 题解
    属于是将矩阵快速幂的绝大部分技巧用到了极致的一道题。暴力部分首先我们先考虑一个普通DP。定义\(dp_{t,i}\)表示在时间为\(t\)时到达点\(i\)可以得到的愉悦值之和的最大值。显然有\((i,j)\inE\todp_{t+w,j}=\max(dp_{t,i}+c_j)\)。特判一下当前节点有美食节的情......
  • 洛谷 P5175 数列 题解
    纯纯数学题。看到\(n\le10^{18}\)不难想到矩乘,但是\(\log_210^{18}\approx60\),再加上\(T=30000\)的多测,运算量已经来到了\(1.8\times10^6\),所以我们最多有一个\(\sqrt[3]{\frac{1.5\times10^8}{6\times10^6}}\approx4\)的矩阵。\[\becausea_i=xa_{i-1}+ya_{......
  • Project Euler 588 题解
    这玩意好像甚至有递推式……不太懂(为什么是图片?cnblogs第一个公式没渲染成功)时间复杂度是\(O(4^{\degF}\logK)\)的。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmaxn=100;intf[17][maxn],cur[10],al[4];intcalc(intK){ //cer......
  • 题解:[SNCPC2019] Pick Up
    ProblemLink[SNCPC2019]PickUp题意给出甲的坐标和速度,乙的坐标和速度,商场的坐标,可以让乙去接甲,求甲前往商场的最短用时。Solution分类讨论。思考乙是否要去接甲。这个很简单,令\(ans1\)为甲自己出发耗时,\(ans2\)为乙接甲耗时,两者取最小值即可。\(ans1\)很好算,那么\(......
  • P3794 签到题IV 题解
    题目传送门前置知识最大公约数解法\(\gcd\)和\(\operatorname{or}\)在固定左端点的情况下至多会变化\(O(\logV)\)次。以\(\gcd\)为例,考虑求出所有的四元组\((l,r,x,val)\)表示\(\foralli\in[l,r],\gcd\limits_{j=i}^{x}\{a_{j}\}=val\)。本题中因为\(x\)......