模拟赛2021.4.5

T3

题意:有矩阵\(A\)与置换\(P\),给出\(A_1\).\(A_i\)=\(P(A_{i-1})\),求\(\det(A)\)

不难发现,当置换\(P\)的循环拆分个数大于\(1\)时,答案为\(0\)

不妨设拆分成了\(2\)个循环,为\(x\)与\(y\),其中\(|x|\leq |y|\)

则会发现后\(|y|\)行消去前\(|x|\)行后线性相关

大于\(2\)时归纳易证

所以我们现在就是要求一个循环矩阵\(A\)的行列式

\[A=\left[\begin{matrix}a_0&a_1&\cdots&a_{n-1}\\a_{n-1}&a_0&\cdots&a_{n-2}\\\vdots&\vdots&\ddots&\vdots\\a_1&a_2&\cdots&a_0\end{matrix}\right] \]

设矩阵\(C=\left[\begin{matrix}1&1&\cdots&1\\1&\omega^1_n&\cdots&\omega^{n-1}_n\\1&\omega^2_n&\cdots&\omega^{2(n-1)}_n\\\vdots&\vdots&\ddots&\vdots\\1&\omega^{n-1}_n&\cdots&\omega^{(n-1)^2}_n\end{matrix}\right]\)

因为\(C\)为范德蒙矩阵

所以\(\det(C)=\sum_{0\leq i<j<n}(\omega^j-\omega^i)\not =0\)

所以\(C\)为非奇异矩阵

设\(f(x)=\sum_{i=0}^{n-1}a_ix^i\)

\[AC=\left[\begin{matrix}f(1)&f(\omega)&f(\omega^2)&\cdots&f(\omega^{n-1})\\ f(1)&\omega f(\omega)&\omega^2 f(\omega^2)&\cdots&\omega^{n-1} f(\omega^{n-1})\\\vdots&\vdots&\vdots&\ddots&\vdots\\f(1)&\omega^{(n-1)} f(\omega)&\omega^{2(n-1)} f(\omega^2)&\cdots&\omega^{(n-1)^2} f(\omega^{n-1})\end{matrix}\right]=\left(\prod_{i=0}^{n-1}f(\omega^i)\right)C\\ \Leftrightarrow \det(A)\det(C)=\left(\prod_{i=0}^{n-1}f(\omega^i)\right)\det(C)\\ \Leftrightarrow \det(A)=\prod_{i=0}^{n-1}f(\omega^i) \]

所以怎么求\(\prod_{i=0}^{n-1}f(\omega^i)\)呢?

如果不带模,我们可以直接用离散傅里叶变换

可是带模

我们可以发现,\(\omega^i\)其实就是多项式\(g(x)=x^n-1\)的根

设\(\lambda_{0\sim n-1}\)表示\(n\)次多项式\(A\)的\(n\)个根

设\(\zeta_{0\sim m-1}\)表示\(m\)次多项式\(B\)的\(m\)个根

则\(A=([x^n]A)\prod_{i=0}^{n-1}(x-\lambda_i)\)

定义函数\(\gamma(A,B)\)表示\(([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)\)

\[\begin{align} \gamma(A,B)&=([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)\\ &=([x^m]B)^n\prod_{i=0}^{m-1}([x^n]A)\prod_{j=0}^{n-1}(\zeta_i-\lambda_j)\\ &=([x^m]B)^n([x^n]A)^m\prod_{i=0}^{m-1}\prod_{j=0}^{n-1}(\zeta_i-\lambda_j)\\ &=(-1)^{nm}([x^n]A)^m\prod_{i=0}^{n-1}B(\lambda_i)\\ &=(-1)^{nm}\gamma(B,A) \end{align} \]

\[\begin{align} \gamma(A-B,B)&=([x^m]B)^n\prod_{i=0}^{m-1}(A(\zeta_i)-B(\zeta_i))\\ &=([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)\\ &=\gamma(A,B) \end{align} \]

\[\gamma(A,B)=A^m(A为常函数) \]

\[\begin{align} \gamma(kA,B)&=([x^m]B)^n\prod_{i=0}^{m-1}kA(\zeta_i)\\ &=([x^m]B)^nk^m\prod_{i=0}^{m-1}A(\zeta_i)\\ &=k^m\gamma(A,B) \end{align} \]

同理\(\gamma(A,kB)=(-1)^{nm}\gamma(kB,A)=k^n\gamma(A,B)\)

这样我们就可以像\(\tt gcd\)一样在\(O(n^2)\)的时间内求出来了

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;char k;bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define mod 1000000007
int s,q[5005],a[5005],b[5005];
ll qkpow(ll n,int m){
	ll t=1;
	for(;m;m>>=1,n=n*n%mod)
		if(m&1)t=t*n%mod;
	return t;
}
int main(){fre("matrix");
	s=read;
	for(int i=1;i<=s;++i)a[i]=read;
	for(int i=1;i<=s;++i)q[read]=i;
	for(int i=1,t=1;t<=s;++t,i=q[i]){
		if(i==1&&t!=1)return puts("0"),0;
		b[t]=i;
	}ll ans=1;
	for(int i=1;i<=s;b[i-1]=a[b[i]],++i)
		for(int j=i+1;j<=s;++j)
			if(b[i]>b[j])
				ans=-ans;
	memset(a,0,sizeof(a));
	int n=s,m=s-1;
	a[n]=1;a[0]=-1;
	while(1){
		if(n<m)swap(n,m),(n&m&1)&&(ans=-ans),swap(a,b);
		if(!m){
			ans=ans*qkpow(b[0],n)%mod;
			break;
		}
		for(int i=n-m;~i;--i){
			if(!a[i+m])continue;
			ll x=qkpow(b[m],mod-2)*a[i+m]%mod;
			for(int j=0;j<=m;++j)
				a[i+j]=(a[i+j]-b[j]*x)%mod;
		}
		int tv=n;
		while(!a[n]&&n)--n;
		ans=ans*qkpow(b[m],tv-n)%mod;
	}printf("%lld",(ans+mod)%mod);
	return 0;
}
### T3

> 题意:有矩阵$A$与置换$P$,给出$A_1$.$A_i$=$P(A_{i-1})$,求$\det(A)$

不难发现,当置换$P$的循环拆分个数大于$1$时,答案为$0$

不妨设拆分成了$2$个循环,为$x$与$y$,其中$|x|\leq |y|$

则会发现后$|y|$行消去前$|x|$行后线性相关

大于$2$时归纳易证



所以我们现在就是要求一个循环矩阵$A$的行列式
$$
A=\left[\begin{matrix}a_0&a_1&\cdots&a_{n-1}\\a_{n-1}&a_0&\cdots&a_{n-2}\\\vdots&\vdots&\ddots&\vdots\\a_1&a_2&\cdots&a_0\end{matrix}\right]
$$
设矩阵$C=\left[\begin{matrix}1&1&\cdots&1\\1&\omega^1_n&\cdots&\omega^{n-1}_n\\1&\omega^2_n&\cdots&\omega^{2(n-1)}_n\\\vdots&\vdots&\ddots&\vdots\\1&\omega^{n-1}_n&\cdots&\omega^{(n-1)^2}_n\end{matrix}\right]$

因为$C$为范德蒙矩阵

所以$\det(C)=\sum_{0\leq i<j<n}(\omega^j-\omega^i)\not =0$

所以$C$为非奇异矩阵



设$f(x)=\sum_{i=0}^{n-1}a_ix^i$
$$
AC=\left[\begin{matrix}f(1)&f(\omega)&f(\omega^2)&\cdots&f(\omega^{n-1})\\
 f(1)&\omega f(\omega)&\omega^2 f(\omega^2)&\cdots&\omega^{n-1} f(\omega^{n-1})\\\vdots&\vdots&\vdots&\ddots&\vdots\\f(1)&\omega^{(n-1)} f(\omega)&\omega^{2(n-1)} f(\omega^2)&\cdots&\omega^{(n-1)^2} f(\omega^{n-1})\end{matrix}\right]=\left(\prod_{i=0}^{n-1}f(\omega^i)\right)C\\
\Rightarrow \det(A)\det(C)=\left(\prod_{i=0}^{n-1}f(\omega^i)\right)\det(C)\\
\Rightarrow \det(A)=\prod_{i=0}^{n-1}f(\omega^i)
$$
所以怎么求$\prod_{i=0}^{n-1}f(\omega^i)$呢?

如果不带模,我们可以直接用离散傅里叶变换

可是带模

我们可以发现,$\omega^i$其实就是多项式$g(x)=x^n-1$的根

设$\lambda_{0\sim n-1}$表示$n$次多项式$A$的$n$个根

设$\zeta_{0\sim m-1}$表示$m$次多项式$B$的$m$个根

则$A=([x^n]A)\prod_{i=0}^{n-1}(x-\lambda_i)$

 定义函数$\gamma(A,B)$表示$([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)$
$$
\begin{align}
\gamma(A,B)&=([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)\\
&=([x^m]B)^n\prod_{i=0}^{m-1}([x^n]A)\prod_{j=0}^{n-1}(\zeta_i-\lambda_j)\\
&=([x^m]B)^n([x^n]A)^m\prod_{i=0}^{m-1}\prod_{j=0}^{n-1}(\zeta_i-\lambda_j)\\
&=(-1)^{nm}([x^n]A)^m\prod_{i=0}^{n-1}B(\lambda_i)\\
&=(-1)^{nm}\gamma(B,A)
\end{align}
$$

$$
\begin{align}
\gamma(A-B,B)&=([x^m]B)^n\prod_{i=0}^{m-1}(A(\zeta_i)-B(\zeta_i))\\
&=([x^m]B)^n\prod_{i=0}^{m-1}A(\zeta_i)\\
&=\gamma(A,B)
\end{align}
$$


$$
\gamma(A,B)=A^m(A为常函数)
$$

$$
\begin{align}
\gamma(kA,B)&=([x^m]B)^n\prod_{i=0}^{m-1}kA(\zeta_i)\\
&=([x^m]B)^nk^m\prod_{i=0}^{m-1}A(\zeta_i)\\
&=k^m\gamma(A,B)
\end{align}
$$

同理$\gamma(A,kB)=(-1)^{nm}\gamma(kB,A)=k^n\gamma(A,B)$

这样我们就可以像$\tt gcd$一样在$O(n^2)$的时间内求出来了

```cpp
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;char k;bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define mod 1000000007
int s,q[5005],a[5005],b[5005];
ll qkpow(ll n,int m){
	ll t=1;
	for(;m;m>>=1,n=n*n%mod)
		if(m&1)t=t*n%mod;
	return t;
}
int main(){fre("matrix");
	s=read;
	for(int i=1;i<=s;++i)a[i]=read;
	for(int i=1;i<=s;++i)q[read]=i;
	for(int i=1,t=1;t<=s;++t,i=q[i]){
		if(i==1&&t!=1)return puts("0"),0;
		b[t]=i;
	}ll ans=1;
	for(int i=1;i<=s;b[i-1]=a[b[i]],++i)
		for(int j=i+1;j<=s;++j)
			if(b[i]>b[j])
				ans=-ans;
	memset(a,0,sizeof(a));
	int n=s,m=s-1;
	a[n]=1;a[0]=-1;
	while(1){
		if(n<m)swap(n,m),(n&m&1)&&(ans=-ans),swap(a,b);
		if(!m){
			ans=ans*qkpow(b[0],n)%mod;
			break;
		}
		for(int i=n-m;~i;--i){
			if(!a[i+m])continue;
			ll x=qkpow(b[m],mod-2)*a[i+m]%mod;
			for(int j=0;j<=m;++j)
				a[i+j]=(a[i+j]-b[j]*x)%mod;
		}
		int tv=n;
		while(!a[n]&&n)--n;
		ans=ans*qkpow(b[m],tv-n)%mod;
	}printf("%lld",(ans+mod)%mod);
	return 0;
}
上一篇:Bluestein's Algorithm学习笔记


下一篇:LGV引理学习笔记