生成树计数裸题,因为模数不是质数所以要用辗转相除的高斯消元。
de了很久的bug然后发现一个变量A赋值后下一行又申明了一个新的临时变量A(:
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
const int mod=2007;
const int N=507;
typedef long long LL;
using namespace std;
int T,n,g[N][N],ans;
template<typename T> void read(T &x) {
T f=1; x=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int guess(int n) {
int res=1,f=1;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
int A=g[i][i],B=g[j][i];
while(B) {
int t=A/B; A=A%B; swap(A,B);
for(int k=i;k<=n;k++)
g[i][k]=(g[i][k]-t*g[j][k]%mod+mod)%mod;
for(int k=i;k<=n;k++)
swap(g[i][k],g[j][k]);
f=-f;
}
}
if(!g[i][i]) return 0;
res=(res*g[i][i])%mod;
}
if(f==-1) res=(mod-res)%mod;
return res;
}
int main() {
read(T);
while(T--) {
read(n);
if(n==1) printf("4
");
else if(n==2) printf("40
");
else {
int tot=n;
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++) {
if(i==1) g[i][n]--,g[i][2]--;
else if(i==n) g[i][1]--,g[i][i-1]--;
else g[i][i-1]--,g[i][i+1]--;
g[i][i]+=4;
}
for(int i=1;i<=tot;i++) {
int x=n+1,y=n+2,z=n+3,w=(i==n)?1:i+1;
g[x][i]--; g[i][x]--;
g[x][y]--; g[y][x]--;
g[y][z]--; g[z][y]--;
g[z][w]--; g[w][z]--;
g[x][x]+=2; g[y][y]+=2; g[z][z]+=2;
n+=3;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
(g[i][j]+=mod)%=mod;
}
ans=guess(n-1);
printf("%d
",ans);
}
}
return 0;
}