题意:给你一个p 和一个只有小写字母或者*的字符串,1 = a ,2 = b,0 = *,字符串长度为n,代表f(k)
f (k) = ∑0<=i<=n-1aiki
求a[i] (0 <= i < n)
这题的系数矩阵是范德蒙德行列式。。所以解集是唯一的。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
int var , equ , p;
LL a[111][111] , x[111];
char s[111];
void init()
{
int i,j;
for(i = 0;i < equ; i++)
{
a[i][0] = 1;
for(j = 1;j < var; j++)
a[i][j] = (a[i][j-1]*(i+1))%p;
}
}
LL gcd(LL a,LL b)
{
return b ? gcd(b , a%b) : a;
}
LL lcm(LL a,LL b)
{
return a/gcd(a,b)*b;
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(b == 0)
{
x = 1;y = 0;
return a;
}
LL ans = exgcd(b, a%b , y,x);
y = y-a/b*x;
return ans;
}
void debug()
{
puts("debug");
int i,j;
for(i = 0;i < equ ;i++)
{
for(j = 0 ;j < var+1;j ++)
printf("%d ", a[i][j]);
puts("");
}
puts("end");
}
void gauss()
{
//debug();
int i,j,k;
int row = 0 , col = 0;
for( ; row < equ && col < var; row++ , col++)
{
int maxr = row;
for(i = row+1;i < equ; i++)
if(abs(a[i][col]) > abs(a[maxr][col]))
maxr = i;
if(a[maxr][col] == 0)
{
row--;
continue;
}
if(maxr != row)
for(i = col;i < equ+1;i ++)
swap(a[row][i] , a[maxr][i]);
for(i = row+1;i < equ; i++)
{
if(a[i][col] == 0)
continue;
LL LCM = lcm(abs(a[i][col]) , abs(a[row][col])) ;
LL aa = LCM / abs(a[row][col]) , bb = LCM / abs(a[i][col]);
if(a[row][col] * a[i][col] < 0)
aa = -aa;
for(j = col; j < var +1; j++)
a[i][j] = (a[i][j]*bb - aa*a[row][j])%p;
}
}
//debug();
for(i = var-1;i >= 0; i--)
{
x[i] = a[i][var];
for(j = i + 1;j < var; j++)
x[i] -= a[i][j]*x[j];
if(x[i] == 0)
continue;
LL xx , yy;
LL ans = exgcd(a[i][i] , p , xx , yy);
xx = xx/ans*x[i];
x[i] = (xx%p+p)%p;
}
for(i = 0;i < var; i ++)
printf("%d ", x[i]);
puts("");
}
int main()
{
int i,t;
scanf("%d", &t);
while(t--)
{
scanf("%d%s", &p ,s);
int len = strlen(s);
var = equ = len;
init();
for(i = 0;i < len ;i ++)
if(s[i] == '*')
a[i][var] = 0;
else
a[i][var] = s[i]-'a'+1;
gauss();
}
return 0;
}