POJ 2065 SETI 高斯消元解線性同余方程


題意:

給出mod的大小,以及一個不大於70長度的字符串。每個字符代表一個數字,且為矩陣的增廣列。系數矩陣如下

1^0 * a0 + 1^1 * a1 + ... + 1^(n-1) * an-1  =  f(1)

2^0 * a0 + 2^1 * a1 + ... + 2^(n-1) * an-1    =  f(2)

........

n^0 * a0 + n^1 * a1 + ... + n^(n-1) * an-1   =  f(n)

快速冪取模下系數矩陣

#include <cstdio>
#include
<cstring>
#include
<algorithm>
using namespace std;

const int MAXN = 100;
int a[MAXN][MAXN], x[MAXN];
int MOD;

void debug(int n, int m)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
printf(
"%d ", a[i][j]);
printf(
" %d\n", a[i][m]);
}
puts(
"**************************************************************");
}

int powermod(int a,int b)
{
int ans=1;
a
%=MOD;
while(b)
{
if(b&1) ans=ans*a%MOD;
a
=a*a%MOD;
b
=b>>1;
}
return ans;
}

int gcd(int a,int b) //遞歸算法
{
return b ? gcd(b, a%b) : a;
}

int lcm(int a, int b)
{
return a*b/gcd(a,b);
}

int Guass(int equ,int var)
{
// debug(equ, var);
int row,col;
row
=col=0;
while(row<equ && col<var)
{
//列非零主
int r=row;
for(int i=row; i<equ; i++)
if(a[i][col]!=0)
{
r
=i;
break;
}
if(r!=row)
{
for(int j=col; j<var+1; j++)
swap(a[row][j],a[r][j]);
}
if(a[row][col]==0)//說明有自由變元
{
col
++;
continue;
}
//消元
for(int i=row+1; i<equ; i++)
{
if(a[i][col]==0) continue;
int l = lcm(a[row][col],a[i][col]);
int ta = l/a[row][col];
int tb = l/a[i][col];
for(int j=col; j<var+1; j++)
a[i][j]
= ((tb*a[i][j] - ta*a[row][j]) % MOD + MOD) %MOD;
}
// debug(equ, var);
row++;
col
++;
}
// for(int i=row; i<equ; i++)
// if(a[i][var]!=0) return -1;
// if(row < var) return 1;
for(int i=row-1; i>=0; i--)
{
int tmp = a[i][var];
for(int j=i+1; j<var; j++)
tmp
= ((tmp - x[j]*a[i][j])%MOD + MOD)%MOD;
while(tmp%a[i][i]) tmp += MOD;
x[i]
= tmp/a[i][i]%MOD;
}
return 0;
}

char s[100];

int main()
{
// freopen("in.txt", "r", stdin);
int t;
scanf(
"%d", &t);
while(t--)
{
scanf(
"%d%s", &MOD, s);
int n = strlen(s);
memset(a,
0, sizeof(a));
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
a[i][j]
= powermod(i+1,j);
for(int i=0; i<n; i++)
a[i][n]
= s[i]=='*'? 0:s[i]-'a'+1;
Guass(n, n);
for(int i=0; i<n; i++)
{
if(x[i]<0) x[i] += MOD;
printf(
"%d%c", x[i], i==n-1? '\n':' ');
}
}
return 0;
}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com