矩阵与线性方程组专题
2016-02-29 13:24
232 查看
矩阵与线性方程组专题
UVA 10870 Recurrences
UVA 1386LA 3704 Cellular Automaton
UVA 10828 Back to Kernighan-Ritchie
UVA 11542 Square
UVA 10655 Contemplation Algebra
UVA 11149 Power of Matrix
UVA 10808 Rational Resistors
UVA 1332 Kids Problem
递推
1≤n≤500,1≤k≤107,1≤106≤m,0≤d≤n/21 \le n \le 500 , 1 \le k \le 10^7,1 \le 10^6 \le m, 0 \le d \le n/2
列成矩阵,发现要求循环矩阵的k次方
(循环矩阵就是从第二行开始每一行为上一行循环右移一列的结果。)
结论:两个循环矩阵的乘积还是循环矩阵。
循环矩阵只需要保存一行,因此矩阵乘法的复杂度只有O(n2)O(n^2)
列方程,可能出现矛盾方程,多余方程
不难发现,矛盾方程的情况说明解为无穷大,自由变量的情况说明不在同一连通块。
gauss_xor方程组,注意位压
令f(n)=an+bnf(n)=a^n+b^n
则(an−1+bn−1)(a+b)=an+bn+ab(an−2+bn−2)(a^{n-1}+b^{n-1})(a+b)=a^n+b^n+ab(a^{n-2}+b^{n-2})
f(n−1)p=f(n)+qf(n−2)f(n-1)p=f(n)+qf(n-2)
f(n)=pf(n−1)−qf(n−2)f(n)=pf(n-1)-qf(n-2)
列节点电压方程
特殊情况:2点不连通,电阻为正无穷
求这个方程是否有解,若有解则输出最小的合法解的和
n≤16n \le 16
考虑模方程组消元,可以用辗转相减法
然后暴力搜索,靠玄学拉。。
UVA 10870 Recurrences
UVA 1386LA 3704 Cellular Automaton
UVA 10828 Back to Kernighan-Ritchie
UVA 11542 Square
UVA 10655 Contemplation Algebra
UVA 11149 Power of Matrix
UVA 10808 Rational Resistors
UVA 1332 Kids Problem
矩阵与线性方程组专题
UVA 10870 Recurrences
题意:第n个Fib数递推
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (10) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } const int MAXN =(20) ; int n,m,d; ll a[MAXN]; struct M { int n,m; ll a[MAXN][MAXN]; M(int _n=0){n=m=_n;MEM(a);} M(int _n,int _m){n=_n,m=_m;MEM(a);} void mem (int _n=0){n=m=_n;MEM(a);} void mem (int _n,int _m){n=_n,m=_m;MEM(a);} friend M operator*(M a,M b) { M c(a.n,b.m); For(k,a.m) For(i,a.n) For(j,b.m) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%(::m); return c; } void make_I(int _n) { n=m=_n; MEM(a) For(i,n) a[i][i]=1; } }A; M pow2(M a,ll b) { M c;c.make_I(a.n); static bool a2[1000000]; int n=0;while (b) a2[++n]=b&1,b>>=1; For(i,n) { if (a2[i]) c=c*a; a=a*a; } return c; } int f[MAXN]; int main() { // freopen("uva10870.in","r",stdin); // freopen(".out","w",stdout); while(cin>>d>>n>>m) { if (!d && !n && !m) return 0; For(i,d) scanf("%lld",&a[i]); For(i,d) scanf("%lld",&f[i]),f[i]%=m; if (n<=d) { cout<<f <<endl; continue; } A.mem(d); For(i,d) For(j,d) { if (i<d) A.a[i][j] = (i == j-1 ); else A.a[i][j]=a[d-j+1]; } A=pow2(A,n-d); ll ans=0; For(j,d) ans = (ans + A.a[d][j] * f[j] %m ) % m; cout<<ans<<endl; } return 0; }
UVA 1386/LA 3704 Cellular Automaton
题意:给一个环,上面有n个格子,每次操作把格子的值变为与它距离不超过d的格子在操作之前的值的和%m,求k次操作后的值1≤n≤500,1≤k≤107,1≤106≤m,0≤d≤n/21 \le n \le 500 , 1 \le k \le 10^7,1 \le 10^6 \le m, 0 \le d \le n/2
列成矩阵,发现要求循环矩阵的k次方
(循环矩阵就是从第二行开始每一行为上一行循环右移一列的结果。)
结论:两个循环矩阵的乘积还是循环矩阵。
循环矩阵只需要保存一行,因此矩阵乘法的复杂度只有O(n2)O(n^2)
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (500 + 10) int n,m,d,k; struct M { int n,m; ll a[2][MAXN]; M(int _n=0){n=m=_n;MEM(a);} M(int _n,int _m){n=_n,m=_m;MEM(a);} void mem (int _n=0){n=m=_n;MEM(a);} void mem (int _n,int _m){n=_n,m=_m;MEM(a);} int get(int i,int j) { int t=(j-i+1+n) % n; return (t == 0) ? a[1] : a[1][t]; } friend M operator*(M a,M b) { M c(a.n); For(k,a.n) For(j,b.m) c.a[1][j]=(c.a[1][j]+a.a[1][k]*b.get(k,j) )%(::m); return c; } void make_I(int _n) { n=m=_n; MEM(a) a[1][1] = 1; } }A,c; void pow2(ll b) { c.make_I(A.n); static bool a2[1000000]; int n=0;while (b) a2[++n]=b&1,b>>=1; For(i,n) { if (a2[i]) c=c*A; A=A*A; } } ll a[MAXN],ans[MAXN]; int main() { // freopen("la3704.in","r",stdin); // freopen(".out","w",stdout); while (cin>>n>>m>>d>>k){ For(i,n) a[i] = read(); A.mem(n); For(j,n) if (min(abs(1-j),n-abs(1-j))<=d) { A.a[1][j]=1%m; } pow2(k); A=c; For(i,n) { ans[i]=0; For(j,n) ans[i]=(ans[i] + a[j]*A.get(i,j)%m ) %m; } PRi(ans,n) } return 0; }
UVA 10828 Back to Kernighan-Ritchie
题意:给一个马尔可夫过程,求每个点期望执行次数。列方程,可能出现矛盾方程,多余方程
不难发现,矛盾方程的情况说明解为无穷大,自由变量的情况说明不在同一连通块。
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define eps (1e-8) #define MAXN (100+10) typedef double Matrix[MAXN][MAXN]; void gauss_jordan(Matrix A, int n) { //矛盾方程和多余方程都可以 A[0..n-1,0..n] //运行结束后A[i][i]极为第i个变量的值 Rep(i,n) { int r=i; Fork(j,i+1,n-1) { if (fabs(A[j][i])>fabs(A[r][i])) r=j; } if (fabs(A[r][i]) < eps ) continue; if (r>i) { Rep(j,n+1) swap(A[r][j],A[i][j]); } Rep(k,n) if (k^i) { double f = A[k][i] / A[i][i]; ForkD(j,i,n) A[k][j] -= f * A[i][j]; } } } int n,d[MAXN]; vector<int> Prev[MAXN]; bool flag[MAXN]; int main() { // freopen("uva10828.in","r",stdin); // freopen(".out","w",stdout); int kcase=0; while(cin>>n && n ) { printf("Case #%d:\n",++kcase); For(i,n) Prev[i].clear(),d[i]=0; int a,b; while(scanf("%d%d",&a,&b)==2 &&a ) { Prev[b].pb(a); d[a]++; } Matrix A; Rep(i,n) Rep(j,n+1) A[i][j]=0; A[0] =1; For(i,n){ A[i-1][i-1]=1; int m=SI(Prev[i]); Rep(k,m) { int j = Prev[i][k]; A[i-1][j-1] = -1./(double)d[j]; } } gauss_jordan(A,n); MEM(flag) RepD(i,n-1) { if (fabs(A[i][i])<eps && fabs(A[i] ) >eps) flag[i]=1; RepD(j,i-1) if (fabs(A[j][i])>eps && flag[i] ) flag[j]=1; } int q=read(); while(q--) { int i=read();i--; if (flag[i]) puts("infinity"); else printf("%.3lf\n",fabs(A[i][i])<eps ? 0:A[i] / A[i][i]); } } return 0; }
UVA 11542 Square
题意:给一堆数,选出至少一个使乘积为完全平方数,求方案数。gauss_xor方程组,注意位压
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (10086) #define pb push_back #define mp make_pair #define fi first #define se second typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (100000+10) int p[MAXN],tot; bool b[MAXN]={0}; void make_prime(int n) { tot=0; Fork(i,2,n) { if (!b[i]) p[++tot]=i; For(j,tot) { if (i*p[j]>n) break; b[i*p[j]]=1; if (i%p[j]==0) break; } } } int n; ll a[MAXN][2]; int gauss(int n) { For(i,n) { Fork(j,i+1,n) if (a[j][0]>a[i][0] || a[j][0]==a[i][0] && a[j][1]>a[i][1] ) swap(a[i][0],a[j][0]),swap(a[j][1],a[i][1]); if (!a[i][1] && !a[i][0]) return i-1; For(k,n) if (i^k) { if ((a[k][0]^a[i][0])<a[k][0] || (a[k][0]^a[i][0])==a[k][0] && (a[k][1]^a[i][1])<a[k][1] ) { a[k][0]^=a[i][0]; a[k][1]^=a[i][1]; } } } return n; } int main() { // freopen("uva11542.in","r",stdin); // freopen(".out","w",stdout); make_prime(500); // cout<<tot<<endl; int T=read(); while(T--) { n=read(); For(i,n) { ll x; cin>>x; a[i][0]=a[i][1]=0; Rep(j,2) { int t=j*60; for(int k=0;k<60;k++) if( 1<=t+k && t+k<=tot) while (x%p[t+k]==0) { a[i][j] ^= 1LL<<k; x/=p[t+k]; } } } int p=gauss(n); cout<<-1+(1LL<<(n-p))<<endl; } return 0; }
UVA 10655 Contemplation! Algebra
题意:已知p,qp,q(p=a+b,q=abp=a+b,q=ab),求an+bna^n+b^n令f(n)=an+bnf(n)=a^n+b^n
则(an−1+bn−1)(a+b)=an+bn+ab(an−2+bn−2)(a^{n-1}+b^{n-1})(a+b)=a^n+b^n+ab(a^{n-2}+b^{n-2})
f(n−1)p=f(n)+qf(n−2)f(n-1)p=f(n)+qf(n-2)
f(n)=pf(n−1)−qf(n−2)f(n)=pf(n-1)-qf(n-2)
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (10) struct M { int n,m; ll a[MAXN][MAXN]; M(int _n=0){n=m=_n;MEM(a);} M(int _n,int _m){n=_n,m=_m;MEM(a);} void mem (int _n=0){n=m=_n;MEM(a);} void mem (int _n,int _m){n=_n,m=_m;MEM(a);} friend M operator*(M a,M b) { M c(a.n,b.m); For(k,a.m) For(i,a.n) For(j,b.m) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]); return c; } void make_I(int _n) { n=m=_n; MEM(a) For(i,n) a[i][i]=1; } }A; M pow2(M a,ll b) { M c;c.make_I(a.n); static bool a2[1000000]; int n=0;while (b) a2[++n]=b&1,b>>=1; For(i,n) { if (a2[i]) c=c*a; a=a*a; } return c; } ll p,q,n; ll f[3]; int main() { // freopen("uva10655.in","r",stdin); // freopen(".out","w",stdout); while(scanf("%lld%lld%lld",&p,&q,&n)==3) { f[0]=2; f[1]=p; f[2]=p*p-2*q; if (n<=2) { cout<<f <<endl; continue; } A.mem(2); A.a[1][1]=p; A.a[1][2]=-q; A.a[2][1]=1; A.a[2][2]=0; A=pow2(A,n-2); cout<<A.a[1][1]*f[2]+A.a[1][2]*f[1]<<endl; } return 0; }
UVA 11149 Power of Matrix
题意:已知n∗nn*n的矩阵AA,求A+A2+…+AkA+A^2+ \ldots +A^k#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (10) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (40+4) struct M { int n,m; ll a[MAXN][MAXN]; M(int _n=0){n=m=_n;MEM(a);} M(int _n,int _m){n=_n,m=_m;MEM(a);} void mem (int _n=0){n=m=_n;MEM(a);} void mem (int _n,int _m){n=_n,m=_m;MEM(a);} friend M operator*(M a,M b) { M c(a.n,b.m); For(k,a.m) For(i,a.n) For(j,b.m) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F; return c; } friend M operator+(M a,M b) { For(i,a.n) For(j,a.m) a.a[i][j]=(a.a[i][j]+b.a[i][j])%F; return a; } void make_I(int _n) { n=m=_n; MEM(a) For(i,n) a[i][i]=1; } }A; bool a3[1000000]; M pow222(M a,ll b) { M c;c.make_I(a.n); int n=0;while (b) a3[++n]=b&1,b>>=1; c=a; b=1; M d=c; ForD(i,n-1) { b=b*2+a3[i]; c=c*d+c; d=d*d; if (a3[i]) c=c*a+a,d=d*a; } return c; } int n,k; int main() { // freopen("uva11149.in","r",stdin); // freopen(".out","w",stdout); while(cin>>n>>k) { if (!n) break; A.mem(n); For(i,n) For(j,n) cin>>A.a[i][j],A.a[i][j]%=F; A=pow222(A,k); PRi2D(A.a,n,n) puts(""); } return 0; }
UVA 10808 Rational Resistors
题意:给一幅n个节点m条导线的电阻网络,求U,V两点间等效电阻。列节点电压方程
特殊情况:2点不连通,电阻为正无穷
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } ll gcd(ll a,ll b){if (!b) return a;return gcd(b,a%b);} class Frac{ public: ll a,b; Frac():a(0),b(1){} Frac(ll _a,ll _b):a(_a),b(_b){deal();} void deal() { ll d=gcd(a,b); a/=d; b/=d; if (b<0) a=-a,b=-b; } Frac operator+ (const Frac &u) { Frac ans; ans.a = a*u.b + b*u.a; ans.b = b*u.b; ans.deal(); return ans; } Frac operator- (const Frac &u) { Frac ans; ans.a = a*u.b - b*u.a; ans.b = b*u.b; ans.deal(); return ans; } Frac operator* (const Frac &u) { Frac ans; ans.a = a*u.a; ans.b = b*u.b; ans.deal(); return ans; } Frac operator/ (const Frac &u) { Frac ans; ans.a = a*u.b; ans.b = b*u.a; ans.deal(); return ans; } void operator+= (Frac u){ *this = *this + u; } void operator-= (Frac u){ *this = *this - u; } void operator*= (Frac u){ *this = *this * u; } void operator/= (Frac u){ *this = *this / u; } bool operator< (Frac u) {return a*u.b < b*u.a; } bool operator> (Frac u) {return a*u.b > b*u.a; } bool operator== (Frac u) {return a*u.b == b*u.a; } bool operator<= (Frac u) {return a*u.b <= b*u.a; } bool operator>= (Frac u) {return a*u.b >= b*u.a; } bool operator!= (Frac u) {return a*u.b != b*u.a; } bool operator!= (ll c) {return *this != Frac(c,1); } void operator= (ll c){*this = Frac(c,1); } void print(){printf("%lld/%lld",a,b); } }; #define MAXN (30) Frac G[MAXN][MAXN],A[MAXN][MAXN]; class bingchaji { public: int father[MAXN],n; void mem(int _n) { n=_n; For(i,n) father[i]=i; } int getfather(int x) { if (father[x]==x) return x; return father[x]=getfather(father[x]); } void unite(int x,int y) { father[x]=getfather(father[x]); father[y]=getfather(father[y]); father[father[x]]=father[father[y]]; } bool same(int x,int y) { return getfather(x)==getfather(y); } }S; int n,m; void gauss_elimination(int n) { //假设系数矩阵A可逆 A[0..n-1,0..n] //运行结束后A[i][i]极为第i个变量的值 Rep(i,n-1) { int r=-1; Fork(j,i,n-1) { if (A[j][i] != 0 ) r=j; } if (r<0) continue; if (r>i) { Rep(j,n) swap(A[r][j],A[i][j]); } /* 不精确 Fork(k,i+1,n-1) { double f = A[k][i] / A[i][i]; Fork(j,i,n) A[k][j] -= f * A[i][j]; }*/ Fork(k,i+1,n-1) { ForkD(j,i,n-1) A[k][j] -= A[k][i] / A[i][i] * A[i][j]; } } RepD(i,n-2) { Fork(j,i+1,n-2) A[i][n-1] -= A[j][n-1] * A[i][j]; A[i][n-1] /= A[i][i]; } } Frac solve(int u,int v) { int tn=0,tu,tv,t[MAXN]; Rep(i,n) { if (i==u) tu=tn; if (i==v) tv=tn; if (S.same(u+1,i+1)) t[tn++]=i; } tn++; Rep(i,tn) Rep(j,tn) A[i][j]=0; Rep(i,tn-1) Rep(j,tn-1) { if (i==j) continue; Frac p = G[t[i]][t[j]]; A[i][i] += p; A[i][j] -= p; } A[tu][tn-1]=1; A[tv][tn-1]=-1; A[tn-1][0] = 1; gauss_elimination(tn); return A[tu][tn-1]-A[tv][tn-1]; } int main() { // freopen("uva10808.in","r",stdin); // freopen(".out","w",stdout); int T=read(); For(kcase,T) { printf("Case #%d:\n",kcase); n=read(); m=read(); S.mem(n); Rep(i,n) Rep(j,n) G[i][j]=0; For(i,m) { int u,v,r; u=read(); v=read(); r=read(); if (u==v) continue; S.unite(u+1,v+1); G[u][v] += Frac(1,r); G[v][u] += Frac(1,r); } int q=read(); while(q--) { int u=read(),v=read(); printf("Resistance between %d and %d is ",u,v); Frac ans; if (!S.same(u+1,v+1)) printf("1/0"); else { ans = solve(u,v); ans.print(); } puts(""); } puts(""); } return 0; }
UVA 1332 Kid’s Problem
题意:已知一个k元模线性方程组(模数都为n≤10n \le 10)求这个方程是否有解,若有解则输出最小的合法解的和
n≤16n \le 16
考虑模方程组消元,可以用辗转相减法
然后暴力搜索,靠玄学拉。。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<functional> #include<cstdlib> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=Pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (n) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } typedef long long ll; typedef unsigned long long ull; int k,n; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(int a,int b){return (a-b+abs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } #define MAXN (30) #define eps (1e-8) typedef double Matrix[MAXN][MAXN]; ll Ans=INF; int x[MAXN]; Matrix f; void search(int i,int xsum) { if (xsum>=Ans) return; if (i==-1) { Ans=xsum; return; } else { int t = f[i][k]; Fork(j,i+1,k-1) t=sub(t,mul(f[i][j],x[j])); Rep(p,n) { x[i]=p; if (t==mul(x[i],f[i][i])) search(i-1,xsum+p); } } } bool fr[MAXN]; void gauss(Matrix A, int n) { Rep(i,n) { int r=i; Fork(j,i+1,n-1) { if (fabs(A[j][i])>fabs(A[r][i])) r=j; } if (fabs(A[r][i]) < eps ) continue; if (r>i) { Rep(j,n+1) swap(A[r][j],A[i][j]); } Fork(k,i+1,n-1) { while(A[k][i]) { if(A[k][i]>=A[i][i]) { Fork(j,i,n) { A[k][j]=sub(A[k][j],A[i][j]); } } else { Fork(j,i,n) { A[i][j]=sub(A[i][j],A[k][j]); } } } } } Ans=INF; search(n-1,0); if (Ans==INF) puts("No solution"); else cout<<Ans<<endl; } int ans[MAXN]; int main() { // freopen("uva1332.in","r",stdin); // freopen(".out","w",stdout); while (cin>>k>>n && n) { Rep(i,k) ans[i]=(1-read()+n)%n; Rep(i,k) Rep(j,k+1) f[i][j]=0; Rep(i,k) { int p=read(); Rep(j,p) { int a,b; cin>>a>>b; f[a-1][i]=b; } f[i][k]=ans[i]; } gauss(f,k); } return 0; }
相关文章推荐
- 项目经理之什么是项目管理
- Mybatis 批量插入的方法
- 动态规划(一)
- 动态规划(一)
- python学习(1)启程
- Android学习笔记之View(一):LayoutInflater
- Android学习笔记之View(二)
- Array中对象的排序
- 项目经理之项目经理的基本特征
- cassandra介绍
- windows下cocos2dx3.4中打包apk的方法
- 插入排序算法分析
- Android Activity学习 <二> Activity间通讯
- UIViewAlertForUnsatisfiableConstraints
- Android开发之如何监听让Service不被杀死
- RxJava 过滤操作符 ofType
- 1001. A+B Format
- 小米手机与魅族的PK战结果 说明了什么
- Fragment使用
- 乱码问题的解决