1. 程式人生 > >bzoj2467 生成樹

bzoj2467 生成樹

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 生成樹