题目大意:

f[k] = ∑a[i]*k^i % p

每一个f[k]的值就是字符串上第 k 个元素映射的值,*代表f[k] = 0 , 字母代表f[k] = str[i]-'a'+1

把每一个k^i求出保存在矩阵中,根据字符串的长度len,那么就可以得到len行的矩阵,利用高斯消元解决这个线性方程组

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; const int N = ;
//a[i][j]表示线性方程组形成的矩阵上的第i行第j个元素
//x[]保存线性方程组的解集
int a[N][N] , p , x[N];
char str[N]; //求取模的幂运算 x^y % mod
int pow(int x , int y , int mod)
{
int ans = ;
while(y){
if(y & ){
ans *= x;
ans %= mod;
}
x *= x;
x %= mod;
y>>=;
}
return ans;
} int gcd(int a , int b)
{
if(b == ) return a;
else return gcd(b , a%b);
} int lcm(int a , int b)
{
return a/gcd(a , b)*b;//先除后乘防止溢出
} inline int my_abs(int x)
{
return x>=?x:-x;
} inline void my_swap(int &a , int &b)
{
int tmp = a;
a = b , b = tmp;
}
/*
高斯消元解线性方程组的解
有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var
总是考虑上三角部分,所以内部更新总是只更新了上三角部分
*/
int gauss(int equ , int var , int mod)
{
int max_r; // 当前这列绝对值最大的行
int col; // 当前处理的列
int ta , tb;
int Lcm , tmp; for(int i= ; i<var ; i++)
x[i] = ; //转化为阶梯形矩阵
col = ;//一开始处理到第0列
for(int k= ; k<equ ; k++,col++){
/*
枚举当前处理的行
找到该行col列元素绝对值最大的那行与第k行交换,
这样进行除法运算的时候就可以避免小数除以大数了
*/
max_r = k;
for(int i = k+ ; i<equ ; i++)
if(my_abs(a[i][col]) > my_abs(a[max_r][col]))
max_r = i;
if(max_r != k){
//交换两行的数据
for(int i=k ; i<var+ ; i++)
my_swap(a[max_r][i] , a[k][i]);
} if(a[k][col] == ){
//说明该col列第k行以下全是0了,则处理当前行的下一列
k--;
continue;
} for(int i=k+ ; i<equ ; i++){
//枚举要删去的行
if(a[i][col] != ){
Lcm = lcm(my_abs(a[i][col]) , my_abs(a[k][col]));
ta = Lcm / my_abs(a[i][col]);
tb = Lcm / my_abs(a[k][col]);
if(a[i][col] * a[k][col] < ) tb = -tb;//异号相加
for(int j = col ; j<var+ ; j++)
a[i][j] = ((a[i][j]*ta)%mod - (a[k][j]*tb)%mod + mod) % mod;
}
}
}
//唯一解的情况:在var*(var+1) 的增广矩阵中形成严格的上三角阵
//计算x[n-1] , x[n-2] .... x[0] 回代计算,先得到后面的值,推到前面的值
for(int i=var- ; i>= ; i--){
tmp = a[i][var];
for(int j=i+ ; j<var ; j++){
if(a[i][j] != ) tmp -= a[i][j]*x[j];
tmp = (tmp%mod+mod)%mod;
}
while(tmp%a[i][i])
tmp+=mod;
x[i] = (tmp / a[i][i])%mod;
}
return ;
} int main()
{
// freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%d%s" , &p , str);
int len = strlen(str);
//填写矩阵中的元素
for(int i= ; i<len ; i++){
if(str[i] == '*') a[i][len] = ;
else a[i][len] = (int)(str[i] - 'a' + );
for(int j= ; j<len ; j++)
a[i][j] = pow(i+ , j , p);
}
gauss(len , len , p);
for(int i= ; i<len ; i++){
if(i == ) printf("%d" , x[i]);
else printf(" %d" , x[i]);
}
puts("");
}
return ;
}

POJ 2065 高斯消元求解问题的更多相关文章

  1. poj 2065 高斯消元(取模的方程组)

    SETI Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1735   Accepted: 1085 Description ...

  2. POJ 1222 POJ 1830 POJ 1681 POJ 1753 POJ 3185 高斯消元求解一类开关问题

    http://poj.org/problem?id=1222 http://poj.org/problem?id=1830 http://poj.org/problem?id=1681 http:// ...

  3. 【poj2947】高斯消元求解同模方程组【没有AC,存代码】

    题意: p start enda1,a2......ap (1<=ai<=n)第一行表示从星期start 到星期end 一共生产了p 件装饰物(工作的天数为end-start+1+7*x, ...

  4. 【zoj3645】高斯消元求解普通线性方程

    题意: 给你一个方程组(含有12个方程),求(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) 方程组的形式是一个二次方程组 (ai1-x1)^2 + (ai2-x2)^2 +( ...

  5. 【poj1830-开关问题】高斯消元求解异或方程组

    第一道高斯消元题目~ 题目:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关 ...

  6. POJ 1830 开关问题(高斯消元求解的情况)

    开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8714   Accepted: 3424 Description ...

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

    http://poj.org/problem?id=2065 题目是要求 如果str[i] = '*'那就是等于0 求这n条方程在%p下的解. 我看了网上的题解说是高斯消元 + 扩展欧几里德. 然后我 ...

  8. *POJ 1222 高斯消元

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9612   Accepted: 62 ...

  9. POJ 1222 高斯消元更稳

    大致题意: 有5*6个灯,每个灯只有亮和灭两种状态,分别用1和0表示.按下一盏灯的按钮,这盏灯包括它周围的四盏灯都会改变状态,0变成1,1变成0.现在给出5*6的矩阵代表当前状态,求一个能全部使灯灭的 ...

随机推荐

  1. [转载]android常用的API接口调用

    原文地址:android常用的API接口调用作者:宋耀 显示网页:         Uri uri = Uri.parse("http://www.google.com"); In ...

  2. DP Codeforces Round #FF (Div. 1) A. DZY Loves Sequences

    题目传送门 /* DP:先用l,r数组记录前缀后缀上升长度,最大值会在三种情况中产生: 1. a[i-1] + 1 < a[i+1],可以改a[i],那么值为l[i-1] + r[i+1] + ...

  3. 笔记本 windows 10 安装

    开机按快捷键是F12,选择从usb启动.秋叶系统 很好用,推荐使用. 联想笔记本u深度一键u盘启动BIOS设置教程:准备工作:制作好u深度u盘启动盘http://rj.baidu.com/soft/d ...

  4. Markdown基本语法学习

    Markdown是一种纯文本格式的标记语言.通过简单的标记语法,它可以使普通文本内容具有一定的格式. 创始人 John Gruber 的 Markdown 语法说明 Markdown 中文版语法说明 ...

  5. Java多线程——线程的死锁

    Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...

  6. Unity笔记(3)自学第三天

    学习记录: 脚本使用:

  7. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  8. table的数据行tr上下移动

    昨天帮别人解决一个前端页面表格里的数据行上下移动的前端效果,直奔google找了几个demo,发现demo是实现了效果,但是代码很多,最后还是决定自己用jquery写个吧, 首先将前端效果分析出编程逻 ...

  9. Windows提高_2.3第三部分:内核区同步

    第三部分:内核区同步 等待函数(WaitForObject) 等待函数的形式 单个:WaitForSingleObject 多个:WaitForMultipleObjects 一个可以被等待的对象通常 ...

  10. 如何使用crash分析vmcore - 之基础思路case1

    如何使用crash分析vmcore - 之基础思路case1 dmesg查看内核日志 [2493382.671020] systemd-shutdown[1]: Sending SIGKILL to ...