码迷,mamicode.com
首页 > 其他好文 > 详细

BSGS

时间:2015-07-01 22:03:24      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

求解a^x=b(mod p),p为质数时,直接bsgs就可以了。

将x写作km-j,m=sprt(p)时复杂度最优,a^(km)=ba^j(mod p),我们预先求出a^j(j=0~m-1)存入map,然后穷举k=1~p/m,如果map中有值,返回km-cnt[]就可以了。

 

bzoj4128 Matrix

题目大意:a^x=b(mod p),a、b为矩阵。

思路:bsgs直接求就可以了,因为不需要求逆,所以方便许多。(注意map要重定义比较符号)

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
struct use{
    int num[100][100];
    void init()
    {
        int i,j;
        for (i=0;i<100;++i)
          for (j=0;j<100;++j) num[i][j]=1;
    }
    bool operator == (const use & a)const
    {
        int i,j;
        for (i=0;i<100;++i)
          for (j=1;j<100;++j)
            if (num[i][j]!=a.num[i][j]) return false;
        return true;
    }
    bool operator < (const use & a)const
    {
        int i,j;
        for (i=0;i<100;++i)
          for (j=0;j<100;++j)
          {
            if (num[i][j]<a.num[i][j]) return true;
            if (num[i][j]>a.num[i][j]) return false;
          }
        return false;
    }
    bool operator > (const use & a)const
    {
        int i,j;
        for (i=0;i<100;++i)
          for (j=0;j<100;++j)
          {
            if (num[i][j]>a.num[i][j]) return true;
            if (num[i][j]<a.num[i][j]) return false;
          }
        return false;
    }
}a,b;
map <use,int> cnt;
int n,p;
use calc(use m1,use m2)
{
    int i,j,k;
    use m3;
    for (i=1;i<=n;++i)
      for (j=1;j<=n;++j)
      {
          m3.num[i][j]=0;
        for (k=1;k<=n;++k) m3.num[i][j]=(m3.num[i][j]+(m1.num[i][k]*m2.num[k][j])%p)%p;
      }
    return m3;
}
int bsgs()
{
    use m1,m2;
    int i,j,m;
    m1=b;m=sqrt(p);cnt[m1]=1;
    for (i=1;i<m;++i)
    {
        m1=calc(m1,a);cnt[m1]=i+1;
    }
    m1=a;for (i=2;i<=m;++i) m1=calc(m1,a);
    m2=m1;
    for (i=1;i<=p/m;++i)
    {
        if (cnt[m2]!=0) return i*m-cnt[m2]+1;
        m2=calc(m1,m2);
    }
    return 0;
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&p);
    for (i=1;i<=n;++i)
      for (j=1;j<=n;++j) scanf("%d",&a.num[i][j]);
    for (i=1;i<=n;++i)
      for (j=1;j<=n;++j) scanf("%d",&b.num[i][j]);
    printf("%d\n",bsgs());
}
View Code

 

BSGS

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4614514.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!