题意:输入一个素数P,一串字符串str,字符串的每个字符对应一个整数a=1,b=2,c=3····,*=0(输入字符只会是26个小写字母加上*)。
例如str[] = "abc", 那么说明 n=3, 字符串所对应的数列为1, 2, 3。
并且题中定义了一个函数:
a0*1^0 + a1*1^1+a2*1^2+........+an-1*1^(n-1) = f(1), f(1) = str[0] = a = 1;
a0*2^0 + a1*2^1+a2*2^2+........+an-1*2^(n-1) = f(2), f(2) = str[1] = b = 2;
..........
a0*n^0 + a1*n^1+a2*n^2+........+an-1*n^(n-1) = f(n),f(n) = str[n-1] = ````
题解:注意,直接pow(i+1,j)容易溢出。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 100;
int a[MAXN][MAXN], x[MAXN];
int equ, var, P;
inline int gcd ( int a, int b )
{
if ( b == 0 )
return a;
return gcd ( b, a % b );
}
inline int lcm ( int a, int b )
{
return a * b / gcd ( a, b );
}
int mod_mult ( int a, int b, int n )
{
int ret = 0;
a = a % n;
while ( b >= 1 )
{
if ( b & 1 )
{
ret = ret + a;
if ( ret >= n ) ret -= n;
}
a = a << 1;
if ( a >= n ) a -= n;
b = b >> 1;
}
return ret;
}
int mod_exp ( int a, int b, int n )
{
int ret = 1;
a = a % n;
while ( b >= 1 )
{
if ( b & 1 )
ret = mod_mult(ret,a,n);
a = mod_mult(a,a,n);
b >>= 1;
}
return ret;
}
void Debug ()
{
int i, j;
for ( i = 0; i < equ; i++ )
{
for ( j = 0; j <= var; j++ )
printf("%d ",a[i][j]);
printf("\n");
}
printf("\n");
}
int Guass ()
{
int i, j, row, col, mr;
int ta, tb, l, tmp;
row = col = 0;
while ( row < equ && col < var )
{
mr = row;
for ( i = row + 1; i < equ; i++ )
if ( abs(a[i][col]) > abs(a[mr][col]) ) mr = i;
if ( row != mr )
for ( j = col; j <= var; j++ )
swap ( a[row][j], a[mr][j] );
if ( a[row][col] == 0 ) { col++; continue; }
for ( i = row + 1; i < equ; i++ )
{
if ( a[i][col] == 0 ) continue;
l = lcm ( abs(a[i][col]), abs(a[row][col]) );
ta = l / a[i][col]; tb = l / a[row][col];
if ( a[i][col] * a[row][col] < 0 ) tb = -tb;
for ( j = col; j <= var; j++ )
a[i][j] = ( (a[i][j]*ta-a[row][j]*tb) % P + P ) % P;
}
row++; col++;
}
for ( i = row; i < var; i++ )
if ( a[i][var] != 0 ) return -1;
if ( row < var ) return var - row;
for ( i = var - 1; i >= 0; i-- )
{
tmp = a[i][var];
for ( j = i + 1; j < var; j++ )
tmp = ( (tmp-a[i][j]*x[j]) % P + P) % P;
while ( tmp % a[i][i] != 0 ) tmp += P;
x[i] = ( tmp / a[i][i] ) % P;
}
return 0;
}
int main()
{
int t, i, j;
char str[MAXN];
scanf("%d",&t);
while ( t-- )
{
scanf("%d %s",&P, str);
equ = var = strlen(str);
for ( i = 0; i < equ; i++ )
{
if ( str[i] == '*' ) a[i][var] = 0;
else a[i][var] = str[i] - 'a' + 1;
for ( j = 0; j < var; j++ )
a[i][j] = mod_exp(i+1,j, P);
}
//Debug();
Guass();
//Debug();
for ( i = 0; i < var - 1; i++ )
printf("%d ",x[i]);
printf("%d\n",x[var-1]);
}
}