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;
}

 

posted @ 2019-03-04 23:06  LiGuanlin  阅读(92)  评论(0编辑  收藏  举报