题意:给你一个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; }