poj2065 SETI
题目描述:
多组数据,每次给出一个模数$p$和一个表示答案的字符串,
相当于给出一个方程组:$$a_1*1^{1}+a_2*1^{2}+……+a_n*1^{n}=f_1$$
$$a_1*2^{1}+a_2*2^{2}+……+a_n*2^{n}=f_2$$
等等共$n$个方程。
求$a_i$。
题解:
高消时搞一下逆元即可。
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 75; int t,p,n,a[N][N]; char ch[N]; ll fastpow(ll x,int y) { ll ret = 1; while(y) { if(y&1)ret=ret*x%p; x=x*x%p; y>>=1; } return ret; } void gs() { for(int i=1;i<=n;i++) { int tmp = i; for(int j=i+1;j<=n;j++) if(abs(a[j][i])>abs(a[tmp][i]))tmp=j; if(tmp!=i) for(int j=i;j<=n+1;j++)swap(a[i][j],a[tmp][j]); int now=fastpow(a[i][i],p-2); for(int j=i;j<=n+1;j++)a[i][j]=a[i][j]*now%p; for(int j=i+1;j<=n;j++) { now = a[j][i]; for(int k=i;k<=n+1;k++) a[j][k]=(a[j][k]-now*a[i][k]%p+p)%p; } } for(int i=n;i>=1;i--) for(int j=i-1;j>=1;j--) a[j][n+1]=(a[j][n+1]-a[j][i]*a[i][n+1]%p+p)%p; } int main() { scanf("%d",&t); while(t--) { memset(a,0,sizeof(a)); scanf("%d%s",&p,ch+1); n = strlen(ch+1); for(int k=1;k<=n;k++) { int K = 1; for(int i=1;i<=n;i++,K=K*k%p) a[k][i]=K; if(ch[k]>='a'&&ch[k]<='z')a[k][n+1]=ch[k]-'a'+1; } gs(); for(int i=1;i<=n;i++) printf("%d ",a[i][n+1]); puts(""); } return 0; }