您的位置:首页 > 其它

矩阵与线性方程组专题

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

矩阵与线性方程组专题

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: