zoukankan      html  css  js  c++  java
  • [SDOI2011]计算器 BSGS

    前两个操作都看出来做法了,第三个要用到BSGS这个算法

    BSGS主要可以解 a^x=b(mod n)的 0<=x<n 的解

    暂时先拿kb和hzwer的板子当黑盒吧。。数论细节短时间内没有学的打算

    upd:

    学了一下BSGS算法的的理论以及这个板子的实现,似乎这个板子默认模数素数

    模数不素的话用kb的吧,那个似乎是用前向星处理哈希冲突做的。。

    #include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define pb push_back
    #define FOR(a) for(int i=1;i<=a;i++)
    const int inf=0x3f3f3f3f;
    const ll Linf=9e18;
    const int maxn=1e5+7; 
    const ll mod=100003;
    const double eps=1e-6;
    
    int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    void exgcd(int a,int b,int &x,int &y){
    	if(b==0){x=1;y=0;return;}
    	exgcd(b,a%b,x,y);
    	int t=x;x=y;y=t-a/b*y;
    }
    int work1(ll y,int z,int p){
    	y%=p;
    	ll ans=1;
    	for(int i=z;i;i>>=1,y=y*y%p)
    		if(i&1)ans=ans*y%p;
    	//printf("%d
    ",ans);
    	return ans;
    }
    void work2(int y,int z,int p){
    	//xy+tp=z,求x最小正数解
    	int g=gcd(y,p);
    	if(z%g){puts("Orz, I cannot find x!");return;}
    	y/=g;z/=g;p/=g;
    	int a,b;exgcd(y,p,a,b);
    	a=(ll)a*z%p;
    	while(a<0)a+=p;
    	printf("%d
    ",a);
    }
    map<int,int>mp;
    void work3(int y,int z,int p){
    	y%=p;
    	if(!y&&!z){puts("1");return;}
    	if(!y){puts("Orz, I cannot find x!");return;}
    	mp.clear();
    	ll m=ceil(sqrt(p)),t=1;
    	mp[1]=m+1;
    	for(ll i=1;i<m;i++){
    		t=t*y%p;
    		if(!mp[t])mp[t]=i;
    	}
    	ll tmp=work1(y,p-m-1,p),ine=1;
    	for(ll k=0;k<m;k++){
    		int i=mp[z*ine%p];
    		if(i){
    			if(i==m+1)i=0;
    			printf("%lld
    ",k*m+i);
    			return;
    		}
    		ine=ine*tmp%p;
    	}
    	puts("Orz, I cannot find x!");
    }
    int main(){
    	int T,K;scanf("%d%d",&T,&K);
    	for(int i=1;i<=T;i++){
    		int y,z,p;scanf("%d%d%d",&y,&z,&p);
    		if(K==1){
    			int ans=work1(y,z,p);
    			printf("%d
    ",ans);
    		}else if(K==2){
    			work2(y,z,p);
    		}else{
    			work3(y,z,p);
    		}
    	}
    }


  • 相关阅读:
    移动开发iOS&Android对比学习--异步处理
    PHP中文乱码解决办法[转]
    在eclipse里配置Android ndk环境 适用于windows mac 和linux[转]
    android在更新ADT以后报java.lang.NoClassDefFound的解决办法
    在Mac OS下配置PHP开发环境
    在iOS中使用百度地图
    简单说明CentOS源码安装程序
    SecureFXPortable中文乱码
    从Linux下载文件到Windows没有换行问题
    从Windows复制文件到Linux显示乱码问题
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611266.html
Copyright © 2011-2022 走看看