• [SDOI2011]计算器


    通过我的第一篇没看题解的SD省选题祭qwq

    虽然我花了2个上午才调出来

    题目传送门

    1.k=1时,快速幂,不会快速幂的,右转pj***。

    2.k=2时,扩欧,注意要判负。

    这里扯一下判负方法:

    (a)判负,模数为(p),柿子是:

    [(a mod p +p) mod p ]

    3.k=3时,BSGS,我感觉我以前一直在写假的BSGSqwq

    详情见代码。

    
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    using namespace std;
    typedef long long ll;
    
    ll T,k;
    ll y,z,mod;
    ll xx,yy;
    char ch[30]={"Orz, I cannot find x!"};
    map<ll,ll> ma;
    
    inline void readx(ll &x)//快读 
    {
    	x=0;int s=1;char ch=getchar();
    	while(ch<'0'||ch>'9')
    	{if(ch=='-') s=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9')
    	{x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	x*=s;
    }
    
    inline ll qpow(ll b,ll p)//快速幂 
    {
    	ll ans=1;
    	while(p)
    	{
    		if(p&1) ans=ans*b%mod;
    		b=b*b%mod;
    		p>>=1;
    	}
    	return ans;
    }
    
    inline ll gcd(ll a,ll b)//最大公约数,欧几里得算法 
    {
    	if(b==0) {return a;}
    	return gcd(b,a%b);
    }
    
    inline void exgcd(ll a,ll b,ll &xx,ll &yy)//扩欧算法 
    {
    	if(!b) {xx=1;yy=0;return;}
    	exgcd(b,a%b,yy,xx);
    	yy-=a/b*xx;
    }
    
    inline ll inverse(ll x)//费马小定理求逆元 
    {return qpow(x,mod-2);}
    
    inline void bsgs(ll a,ll b)//BSGS算法 
    {
    	a%=mod;b%=mod;
    	ma.clear();
    	ll m=ll(sqrt(mod+1)),e=1;
    	for(int j=0;j<m;++j)//将所有的m-1个a^j计入哈希表里 
    	{
    		if(!ma.count(e)) ma[e]=j;
    		e=e*a%mod;
    	}
    
    	if(gcd(e,mod)!=1) {puts(ch);return;}//如果a^j和模数互质,那BSGS就没法算了,所以无解 
    	ll inv=inverse(e);
    
    	for(int i=0;i<m;++i)
    	{
    		if(ma.count(b))
    		{
    			ll ans=i*m+ma[b];
    			printf("%lld
    ",ans);
    			return;
    		}
    		b=b*inv%mod;
    	}
    	puts(ch);
    }
    
    int main()
    {
    	readx(T);readx(k);
    	if(k==1) while(T--)
    	{
    		readx(y);readx(z);readx(mod);
    		printf("%lld
    ",qpow(y,z));
    	}
    	else if(k==2) while(T--)
    	{
    		readx(y);readx(z);readx(mod);
    		ll g=gcd(y,mod);
    		if(z%g) {puts(ch);continue;}
    		exgcd(y,mod,xx,yy);
    		ll ans=(xx*z/g%mod+mod)%mod;
    		printf("%lld
    ",ans);
    	}
    	else if(k==3) while(T--)
    	{
    		readx(y);readx(z);readx(mod);
    		bsgs(y,z);
    	}
    	return 0;
    }
    //为了好调,我有些压行。不要喷我码风毒瘤啊qwq
     
    

    emmm,分享一下我的学习笔记吧qwq

  • 相关阅读:
    一款纯css3实现的响应式导航
    一款基于TweenMax.js的网页幻灯片
    4款基于jquery的列表图标动画切换特效
    随着鼠标移动的文字阴影
    一款纯css实现的垂直时间线效果
    一款基于jquery的侧边栏导航
    (转) 共享个很棒的vim配置
    [Leetcode] String to Integer (atoi)
    dia无法输入中文?
    [Leetcode] Sum Root to Leaf Numbers
  • 原文地址:https://www.cnblogs.com/oierwyh/p/11372182.html
Copyright © 2020-2023  润新知