ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj2219 数论之神

2021-03-11 08:01:49  阅读:176  来源: 互联网

标签:ci pi return 数论 ll bzoj2219 int include 之神


直接考虑\(x^A\equiv B\pmod{p^c}\),其中\(\gcd(B,p^c)\neq1,B\neq0\)的情况。

分解为\((p^t\cdot h)^A\equiv p^kb\pmod{p^c}\),那么必须有\(A|k\),否则无解。

要求\(tA=k\),那么方程变成\(h^A\equiv b\pmod{p^{c-k}}\)。解出来\(h\)之后他是模\(p^{c-k}\)意义下的,但是实际上\(h\)是在模\(p^{c-\frac{k}{A}}\)意义下的。所以每个解出来的\(h\)都对应\(p^{k-\frac{k}{A}}\)个原方程的值。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define N 1000002
int T,prim[N],cnt,A,B,p,b[N],ci[N],tot,G,pi,fp;
int bb[N],tt;
bool isp[N];
map<int,int>mp;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
void exgcd(int a,int b,ll &x,ll &y)
{if(b==0){x=1;y=0;return;}exgcd(b,a%b,x,y);ll t=y;y=x-a/b*y;x=t;}
inline int inv(int x)
{ll tx,ty;exgcd(x,pi,tx,ty);tx=(tx%pi+pi)%pi;return tx;}
inline int bsgs(int x)
{if(x==1)return 0;
    mp.clear();int tv=1;mp[1]=0;int sqr=sqrt(fp);
    for(int i=1;i<=sqr;i++)
    {
        tv=1ll*tv*G%pi;
        if(!mp.count(tv))mp[tv]=i;
        if(tv==x)return i;
    }int iv=inv(tv);
    for(int i=1;i<=sqr;i++)
    {
        x=1ll*x*iv%pi;
        if(mp.count(x))return i*sqr+mp[x];
    }
}
inline int ksm(int d,int k,int tp)
{int ret=1;while(k){if(k&1)ret=1ll*ret*d%tp;d=1ll*d*d%tp;k>>=1;}return ret;}
inline int cal(int x)
{
    pi=1;for(int i=0;i<ci[x];i++)pi*=b[x];int tB=B%pi;
    fp=pi/b[x]*(b[x]-1);tt=0;
    for(int i=1;i*i<=fp;i++)if(fp%i==0)bb[++tt]=i,bb[++tt]=fp/i;
    for(G=2;G<=100;G++)
    {int i;
        for(i=1;i<=tt;i++)if(bb[i]!=fp&&ksm(G,bb[i],pi)==1)break;
        if(i>tt)break;
    }
    if(!tB)
    {
        int tp=ci[x]/A;if(ci[x]%A)tp++;
        int ret=1;for(int j=0;j<tp;j++)ret*=b[x];
        return pi/ret;
    }
    if(gcd(tB,pi)==1)
    {
        int tb=bsgs(tB);
        int td=gcd(fp,A);
        if(tb%td)return 0;
        return td;
    }
    int k=0,b2=tB;while(b2%b[x]==0)k++,b2/=b[x];
    if(k%A)return 0;
    for(int i=0;i<k;i++)pi/=b[x];
    fp=pi/b[x]*(b[x]-1);
    int tb=bsgs(b2);
    int td=gcd(fp,A);
    if(tb%td)return 0;
    for(int i=0;i<k-k/A;i++)td=td*b[x];
    return td;
}
int main()
{
    for(int i=2;i<=1000000;i++)isp[i]=1;
    for(int i=2;i<=1000000;i++)
    {if(isp[i])prim[++cnt]=i;
        for(int j=1;j<=cnt&&prim[j]*i<=1000000;j++)
        {isp[prim[j]*i]=0;if(i%prim[j]==0)break;}
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&A,&B,&p);p=p<<1|1;tot=0;int tp=p;
        for(int i=1;i<=cnt&&prim[i]<=tp;i++)
        {
            if(tp%prim[i]==0)
            {
                b[++tot]=prim[i];ci[tot]=0;
                while(tp%prim[i]==0)ci[tot]++,tp/=prim[i];
            }
        }if(tp>1)b[++tot]=tp,ci[tot]=1;int ans=1;
        for(int i=1;i<=tot;i++)ans*=cal(i);
        printf("%d\n",ans);
    }
}

标签:ci,pi,return,数论,ll,bzoj2219,int,include,之神
来源: https://www.cnblogs.com/LebronDurant/p/14515458.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有