POJ.2065.SETI(高斯消元 模线性方程组)

题目链接
http://blog.csdn.net/Clove_unique/article/details/54381675
http://blog.csdn.net/u013081425/article/details/24299047
http://blog.csdn.net/lin375691011/article/details/38406737
https://www.cnblogs.com/IMGavin/p/5933037.html

/*
模意义下的高斯消元,在初等行变换时把k=tar/Anow改为k=tag*inv(Anow)
最后求解回带时把除法用乘逆元替代即可
也可用扩展欧几里得求出一个最小的ans[i]
 */
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod p
typedef long long LL;
const int N=100;

namespace Gauss
{
    int p,n,A[N][N],ans[N];
    char s[N];
    int FP(LL x,int k)
    {
        LL t=1;
        for(;k;k>>=1, x=x*x%p)
            if(k&1) t=t*x%p;
        return t;
    }
    inline int inv(int x) {return FP(x,p-2);}
    void Init()
    {
        scanf("%d%s",&p,s);
        n=strlen(s);
        for(int i=0; i<n; ++i)
        {
            A[i][0]=1;
            for(int j=1; j<n; ++j)
                A[i][j]=(i+1)*A[i][j-1]%p;
            A[i][n]= s[i]=='*'?0:s[i]-'a'+1;
        }
    }
    void Solve()
    {
        Init();
        for(int j=0; j<n; ++j)
        {
            int mxrow=j;
            for(int i=j+1; i<n; ++i)
                if(A[i][j]>A[mxrow][j]) mxrow=i;
            if(mxrow!=j) std::swap(A[mxrow],A[j]);
            for(int i=j+1; i<n; ++i)
                if(A[i][j])
                {
                    int t=A[i][j]*inv(A[j][j])%mod;
                    for(int k=j; k<=n; ++k)
                        A[i][k]=((A[i][k]-t*A[j][k]%mod)%mod+mod)%mod;
                }
        }
        for(int i=n-1; ~i; --i)
        {
            for(int j=i+1; j<n; ++j)
                A[i][n]=((A[i][n]-A[i][j]*ans[j]%mod)+mod)%mod;
            ans[i]=A[i][n]*inv(A[i][i])%mod;
        }
        for(int i=0; i<n-1; ++i) printf("%d ",ans[i]);
        printf("%d\n",ans[n-1]);
    }
}

int main()
{
    int t; scanf("%d",&t);
    while(t--) Gauss::Solve();
    return 0;
}/*
3
31 aaa
37 abc
29 hello*earth
*/

原文地址:https://www.cnblogs.com/SovietPower/p/8446229.html

时间: 2024-11-10 10:20:59

POJ.2065.SETI(高斯消元 模线性方程组)的相关文章

POJ 2065 SETI (高斯消元 取模)

题目链接 题意: 输入一个素数p和一个字符串s(只包含小写字母和‘*’),字符串中每个字符对应一个数字,'*'对应0,‘a’对应1,‘b’对应2.... 例如str[] = "abc", 那么说明 n=3, 字符串所对应的数列为1, 2, 3. 题目中定义了一个函数: a0*1^0 + a1*1^1+a2*1^2+........+an-1*1^(n-1) = f(1)(mod p), f(1) = str[0] = a = 1; a0*2^0 + a1*2^1+a2*2^2+....

Poj 2065 SETI (高斯消元)

题目连接: http://poj.org/problem?id=2065 题目描述: 给出和明码长度相同的暗码,暗码的每一个字母f(k)都是由明码ai按照 f (k) = ∑0<=i<=n-1a i *ki(mod p) 转化而来 ,已知暗码,求出明码? 解题思路: 使用高斯消元,重要的就是模型转化,列出来增广矩阵题目就距离AC不远了.这个题目的增广矩阵为: a0*1^0 + a1*1^1 + a2*1^2 + ........ + an*1^n = f(1)(mod p); a0*2^0 +

POJ 2065 SETI 高斯消元解线性同余方程

题意: 给出mod的大小,以及一个不大于70长度的字符串.每个字符代表一个数字,且为矩阵的增广列.系数矩阵如下 1^0 * a0 + 1^1 * a1 + ... + 1^(n-1) * an-1 = f(1) 2^0 * a0 + 2^1 * a1 + ... + 2^(n-1) * an-1   = f(2) ........ n^0 * a0 + n^1 * a1 + ... + n^(n-1) * an-1  = f(n) 快速幂取模下系数矩阵 #include <cstdio> #i

hdu 5755(高斯消元——模线性方程组模板)

知道了是高斯消元后,其实只要稍加处理,就可以解决带模的情况. 1 是在进行矩阵行变化的时候,取模. 2 最后的除法用逆元.(因为a[i][i]必定非0 且小于模数) 然后对于无穷多解的情况,只需要将那些列全为0的未知数定义一个固定值.(这里设的是0)其余操作不变. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath&g

HDU.3571.N-dimensional Sphere(高斯消元 模线性方程组)

题目链接 高斯消元详解 /* $Description$ 在n维空间中给定n+1个点,求一个点使得这个点到所有点的距离都为R(R不给出).点的任一坐标|xi|<=1e17. $Solution$ 根据题意可以列出n+1个二元n次方程,相邻的方程相减可以把二次项和R全部约掉,得到n个一元n次方程. 但需要注意这题数据量较大,最大的可能解范围为1e17,如果利用大数(高精...) 乘法的复杂度会很高 可以采用同余的方法,所有运算需要模一个足够大的素数(>1e17),可以用Miller_Rabin生

POJ 1830 【高斯消元第一题】

首先...使用abs()等数学函数的时候,浮点数用#include<cmath>,其它用#include<cstdlib>. 概念: [矩阵的秩] 在线性代数中,一个矩阵A的列秩是A的线性无关的纵列的极大数目.类似地,行秩是A的线性无关的横行的极大数目. 此题如果有解,解的个数便是2^(自由变元个数),因为每个变元都有两种选择,既1 << n 对于r以下的行,必定全是0,那么如果a[i][n]!=0 必然出现矛盾,于是判定无解. 1 #include <iostr

Poj 1830 高斯消元

开关问题 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5418 Accepted: 2022 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作.你的任

POJ SETI 高斯消元 + 费马小定理

http://poj.org/problem?id=2065 题目是要求 如果str[i] = '*'那就是等于0 求这n条方程在%p下的解. 我看了网上的题解说是高斯消元 + 扩展欧几里德. 然后我自己想了想,就用了高斯消元 + 费马小定理.因为%p是质数,所以很容易就用上了费马小定理,就是在除法的时候用一次就好了.还有就是两个模数相乘还要模一次. #include <cstdio> #include <cstdlib> #include <cstring> #inc

POJ 2947-Widget Factory(高斯消元解同余方程式)

题目地址:id=2947">POJ 2947 题意:N种物品.M条记录,接写来M行,每行有K.Start,End,表述从星期Start到星期End,做了K件物品.接下来的K个数为物品的编号. 此题注意最后结果要调整到3-9之间. 思路: 非常easy想到高斯消元. 可是是带同余方程式的高斯消元,開始建立关系的时候就要MOD 7 解此类方程式时最后求解的过程要用到扩展gcd的思想,举个样例,假设最后得到的矩阵为: 1  1   4 0  6   4 则6 * X2 % 7= 4 % 7  则