bzoj2467 生成樹
阿新 • • 發佈:2018-01-05
algorithm names target ace tchar ++ one bzoj2467 oid
傳送門
生成樹計數裸題,因為模數不是質數所以要用輾轉相除的高斯消元。
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\n");
else if(n==2) printf("40\n");
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\n",ans);
}
}
return 0;
}
View Code
bzoj2467 生成樹