POJ_2065

    题目既然没有说无解的情况就当做一定有解来看待了,根据题意可以列出n个同余方程,然后用高斯消元+拓展欧几里得求得每个ai就可以了。

#include<stdio.h>
#include<string.h>
#include<iostream>
#define MAXD 80
using namespace std;
int mat[MAXD][MAXD], N, P, ans[MAXD];
char b[MAXD], ch[128];
void prepare()
{
    int i;
    for(i = 'a'; i <= 'z'; i ++)
        ch[i] = i - 'a' + 1;
    ch['*'] = 0;
}
void exgcd(int a, int b, int &x, int &y)
{
    if(b == 0)
        x = 1, y = 0;
    else
        exgcd(b, a % b, y, x), y -= x * (a / b);
}
int powmod(int a, int n)
{
    int ans = 1, t = a;
    while(n)
    {
        if(n & 1)
            ans = (ans * t) % P;
        n >>= 1;
        t = (t * t) % P;
    }
    return ans;
}
void init()
{
    int i, j, k;
    scanf("%d", &P);
    scanf("%s", b);
    N = strlen(b);
    for(i = 0; i < N; i ++)
    {
        mat[i][N] = ch[b[i]];
        for(j = 0; j < N; j ++)
            mat[i][j] = powmod(i + 1, j);
    }
}
void gauss()
{
    int i, j, k, a, b, x, y;
    for(i = 0; i < N; i ++)
    {
        if(mat[i][i] == 0)
        {
            for(j = i + 1; j < N; j ++)
                if(mat[j][i])
                {
                    for(k = i; k <= N; k ++)
                        swap(mat[i][k], mat[j][k]);
                    break;
                }
        }
        a = mat[i][i];
        for(j = i + 1; j < N; j ++)
            if(mat[j][i])
            {
                b = mat[j][i];
                for(k = i; k <= N; k ++)
                    mat[j][k] = (mat[j][k] * a - mat[i][k] * b) % P;
            }
    }
    for(i = N - 1; i >= 0; i --)
    {
        a = (mat[i][i] + P) % P, b = mat[i][N];
        for(j = i + 1; j < N; j ++)
            b = (b - mat[i][j] * ans[j]) % P;
        b = (b + P) % P;
        exgcd(a, P, x, y);
        ans[i] = (((x % P) * b) % P + P) % P;
    }
}
void solve()
{
    int i;
    gauss();
    printf("%d", ans[0]);
    for(i = 1; i < N; i ++)
        printf(" %d", ans[i]);
    printf("\n");
}
int main()
{
    int t;
    prepare();
    scanf("%d", &t);
    while(t --)
    {
        init();
        solve();
    }
    return 0;
}
posted on 2012-05-12 13:30  Staginner  阅读(190)  评论(0编辑  收藏  举报