• 【2019.7.26 NOIP模拟赛 T1】数字查找(figure)(数学)


    推式子

    我们设(n=kp+w),则:

    [(kp+w)a^{kp+w}equiv b(mod p) ]

    将系数中的(kp+w)(p)取模,指数中的(kp+w)根据欧拉定理向(p-1)取模,得到:

    [wa^{k+w}equiv b(mod p) ]

    两边同除以(wa^w),得到:

    [a^kequivfrac b{wa^w}(mod p) ]

    求答案

    考虑到(p)很小,因此我们直接枚举(w),则右边式子的值可以通过预处理逆元和幂的逆元,(O(1))计算出来。

    那么我们就是要求出在(0simlfloorfrac {x-w}p floor)范围内存在多少个(k)满足(a^k(mod p))等于我们给定的值。

    由于从小往大枚举(w)(k)的上界递减,因此我们可以采用类似莫队但只有一个端点的方式去维护一个桶,总时间复杂度是(O(p))的。

    代码

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define LL long long
    #define MxX 1000003
    #define min(x,y) ((x)<(y)?(x):(y))
    using namespace std;
    LL n;int a,b,X;
    class MathSolver
    {
    	private:
    		int pw[MxX+5],Ipw[MxX+5],Inv[MxX+5],p[MxX+5];
    	public:
    		I void Solve()
    		{
    			RI i,t=-1,lim;LL k,ans=0;
    			for(Inv[1]=1,i=2;i^X;++i) Inv[i]=1LL*(X-1)*(X/i)%X*Inv[X%i]%X;//预处理逆元
    			for(pw[0]=Ipw[0]=1,i=1;i^X;++i) pw[i]=1LL*pw[i-1]*a%X,Ipw[i]=1LL*Ipw[i-1]*Inv[a]%X;//预处理幂及其逆元
    			for(i=0,t=n/X;i<=t;++i) ++p[pw[i%(X-1)]];//预处理桶
    			for(i=1,lim=min(n,X-1);i<=lim;++i)//枚举余数
    			{
    				k=(n-i)/X;W(t>k) --p[pw[(t--)%(X-1)]];//移动上界
    				ans+=p[1LL*b*Ipw[i%(X-1)]%X*Inv[i]%X];//统计答案
    			}printf("%lld",ans);//输出答案
    		}
    }S;
    int main()
    {
    	freopen("figure.in","r",stdin),freopen("figure.out","w",stdout);
    	return scanf("%d%d%d%lld",&a,&b,&X,&n),a%=X,b%=X,S.Solve(),0;
    }
    
  • 相关阅读:
    2020寒假简记
    感知神经网络模型与学习算法
    信息检索模型与评估
    Diffie-Hellman密钥交换
    RSA密码体制
    MySQL基准测试(benchmark)
    MySQL数据引擎
    MySQL 多版本并发控制(MVCC)
    MySQL事务管理
    利用dotnet restore 导入本地 .nupkg 包
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20190726T1.html
Copyright © 2020-2023  润新知