矩阵与线性方程组专题

来源:互联网 发布:840Mgpu安装tensorflow 编辑:程序博客网 时间:2024/06/07 07:39

  • 矩阵与线性方程组专题
    • 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[n]<<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次操作后的值
1n500,1k107,1106m,0dn/2

列成矩阵,发现要求循环矩阵的k次方
(循环矩阵就是从第二行开始每一行为上一行循环右移一列的结果。)
结论:两个循环矩阵的乘积还是循环矩阵。
循环矩阵只需要保存一行,因此矩阵乘法的复杂度只有O(n2)

#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[n]<<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][n] : 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][n]=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][n]) >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][n] / 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 secondtypedef 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,q(p=a+b,q=ab),求an+bn
f(n)=an+bn
(an1+bn1)(a+b)=an+bn+ab(an2+bn2)
f(n1)p=f(n)+qf(n2)
f(n)=pf(n1)qf(n2)

#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[n]<<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

题意:已知nn的矩阵A,求A+A2++Ak

#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元模线性方程组(模数都为n10
求这个方程是否有解,若有解则输出最小的合法解的和
n16

考虑模方程组消元,可以用辗转相减法
然后暴力搜索,靠玄学拉。。

#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;}
0 0
原创粉丝点击