BSGS

求解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

 

你可能感兴趣的:(B)