zoukankan      html  css  js  c++  java
  • BZOJ 4128: Matrix

    BZOJ 4128: Matrix

    标签(空格分隔): OI BZOJ 大步小步 矩阵 费马小定理


    Time Limit: 10 Sec
    Memory Limit: 128 MB


    Description

    给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p)

    Input

    第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * n的矩阵A.接下来一个n * n的矩阵B

    Output

    输出一个正整数,表示最小的可能的x,数据保证在p内有解

    Sample Input

    2 7
    1 1
    1 0
    5 3
    3 2

    Sample Output

    4

    HINT

    对于100%的数据,n <= 70,p <=19997,p为质数,0<= A_{ij},B_{ij}< p

    保证A有逆


    Solution####

    大步小步算法({A^{x}equiv Bpmod p})
    ({A^{asqrt{p}-b}equiv Bpmod p})
    变换可得({A^{asqrt{p}}equiv B*A^{b}pmod p})
    ({A^{asqrt{p}}pmod{p}})预处理
    在hash表中查找和({B*A^{b}pmod{p}})相同的
    时间复杂度({n^{3}*sqrt{p}})


    Code####

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<bitset>
    #include<vector>
    using namespace std;
    const int N=0,M=0;
    int read()
    {int s=0,f=1;char ch=getchar();
     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
     return s*f;
    }
    //smile please
    int n,P,L;
    int cf[70];
    struct matrix
    {
        long long s[70][70];
     	void one()
           {
    	    for(int i=0;i<n;i++)
    		    for(int j=0;j<n;j++)
    		        s[i][j]=(i==j);
    	   }
        void readin()
           {
    	    for(int i=0;i<n;i++)
    		    for(int j=0;j<n;j++)
    		        s[i][j]=read();
    	   }
        int hash()
           {
           	int ss=0;
           	for(int i=0;i<n;i++)
    		    for(int j=0;j<n;j++)
    		       ss=ss*189211+s[i][j];
            return ss;
    	   }
        void operator*=(matrix b)
           {matrix a;
            for(int i=0;i<n;i++)
    		    for(int j=0;j<n;j++)
    		        a.s[i][j]=s[i][j],
    	            s[i][j]=0;
            for(int j=0;j<n;j++)
               {
    		    for(int i=0;i<n;i++)cf[i]=b.s[i][j];
    			for(int i=0;i<n;i++)
    			   {
      			    for(int k=0;k<n;k++)
                       s[i][j]+=a.s[i][k]*cf[k];
    	            s[i][j]%=P;
    			   }
    		   }
    	   }
    }A,B;
    int he[1<<16],hn[1<<16],hv[1<<16],hl[1<<16],hw=1;
    void put(int u,int v,int l)
    {hw++;hn[hw]=he[u];he[u]=hw;hv[hw]=v;hl[hw]=l;}
    int ans=0;
    int main()
    {
    	n=read(),P=read();
    	A.readin();B.readin();
        L=sqrt(P);ans=-1;
        matrix S=A,k=B;
        for(int i=1;i<=L;i++)
           {k*=A;if(i!=1)S*=A;
    	    int ha=k.hash();
    	    put(ha&((1<<16)-1),ha,i);
    	   }
        matrix SS=S;
        for(int i=L;i<=P+L&&ans==-1;i+=L,SS*=S)
           {
            int ha=SS.hash();
            for(int j=he[ha&((1<<16)-1)];j&&ans==-1;j=hn[j])
               if(hv[j]==ha)
                 ans=i-hl[j];
    	   }
        if(ans==-1)
          printf("no solution
    ");
        else
          printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    期末实训学习认识SSH
    Hibernate 的认识
    action和domain的不同总结
    学习使用action属性来接受参数
    实现action的统配
    struts2学习
    路径问题--笔记
    学习C层
    innovus add_ndr rule
    innovus clock tree instance ccl cdb cwb等 名字命名含义
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5238466.html
Copyright © 2011-2022 走看看