您的位置:首页 > 其它

[POJ2065]SETI(高斯消元)

2017-01-12 20:55 232 查看

题目描述

传送门

题意:

良心博主才会给出题意…

直接说方程是什么吧…

首先a…z=1..26,*=0

读入p(模数且为质数),s(下标从0开始),s长度为n

那么求方程组

10x1+11x2...1n−1xn≡s1(modp)

20x1+21x2...2n−1xn≡s2(modp)

30x1+31x2...3n−1xn≡s3(modp)



n0x1+n1x2...nn−1xn≡sn(modp)

的一组合法解

没有无解或多解的情况

题解

高斯消元求同余方程裸题

就是普通的高斯消元把除法变成乘逆元

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 100

char s
;
int T,Mod,n,K;
int a

,b
,ans
;

void clear()
{
Mod=n=K=0;
memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(ans,0,sizeof(ans));
}
int fast_pow(int x,int p)
{
int ans=1;
for (;p;p>>=1,x=x*x%Mod)
if (p&1)
ans=ans*x%Mod;
return ans;
}
int inv(int x)
{
return fast_pow(x,Mod-2);
}
void gauss()
{
for (int i=1;i<=n;++i)
{
int num=i;
for (int j=i+1;j<=n;++j)
if (a[j][i]>a[num][j]) num=j;
if (num!=i)
{
for (int j=1;j<=n;++j) swap(a[i][j],a[num][j]);
swap(b[i],b[num]);
}
for (int j=i+1;j<=n;++j)
{
int t=a[j][i]*inv(a[i][i])%Mod;
for (int k=1;k<=n;++k)
a[j][k]=((a[j][k]-a[i][k]*t%Mod)%Mod+Mod)%Mod;
b[j]=((b[j]-b[i]*t)%Mod+Mod)%Mod;
}
}
for (int i=n;i>=1;--i)
{
for (int j=i+1;j<=n;++j)
b[i]=((b[i]-a[i][j]*ans[j]%Mod)%Mod+Mod)%Mod;
ans[i]=b[i]*inv(a[i][i])%Mod;
}
}
int main()
{
scanf("%d",&T);
while (T--)
{
clear();
scanf("%d",&Mod);
scanf("%s",s);n=strlen(s);
for (int i=1;i<=n;++i)
{
++K;a[i][1]=1;
for (int j=2;j<=n;++j)
a[i][j]=a[i][j-1]*K%Mod;
if (s[i-1]!='*') b[i]=s[i-1]-'a'+1;
}
gauss();
for (int i=1;i<=n;++i) printf("%d%c",ans[i]," \n"[i==n]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: