zoukankan      html  css  js  c++  java
  • bzoj2219: 数论之神

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2219

    2219: 数论之神

    Time Limit: 3 Sec  Memory Limit: 259 MB
    Submit: 820  Solved: 214
    [Submit][Status][Discuss]

    Description

    在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢?

    Input

    第一行有一个正整数T,表示接下来的数据的组数( T <= 1000) 之后对于每组数据,给出了3个整数A,B,K (1 <= A, B <= 10^9, 1 <= K <= 5 * 10^8)

    Output

    输出一行,表示答案

    Sample Input

    3
    213 46290770 80175784
    3 46290770 80175784
    3333 46290770 80175784

    Sample Output

    27
    27
    297

    HINT

     新加数组一组--2015.02.27

    Source

    数论 鸣谢 AekdyCoin

    不愧是数论之神。。。

    设2*k+1=p1^a1*p2^a2*...*pn^an(不会打数学符号。。。求神犇在评论中告诉我),ans(%(2*k+1))=ans(%p1^a1)*ans(p2^a2)*...*ans(pn^an)。

    所以把2*k+1拆分后分情况计算就好了。

    写了好久。。。又把bsgs里两个变量弄混了,定义了两个y。。。讲道理为什么不会报ce啊。。。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<cmath>
      5 using namespace std;
      6 int T,A,B,k;
      7 long long ans;
      8 long long power(int x,int y){
      9     if(y==0)return 1;
     10     if(y==1)return x;
     11     long long tmp=power(x,y/2);tmp=tmp*tmp;
     12     if(y&1)tmp=tmp*x;
     13     return tmp;
     14 }
     15 long long work1(int A,int B,int p,int cnt){return power(p,cnt-((cnt-1)/A)-1);}
     16 #define base 1000000
     17 int h[base+5],pre[50005],val[50005];
     18 void insert(int x,int y){val[x]=y;y%=base;pre[x]=h[y];h[y]=x;}
     19 int get(int x){
     20     int y=-1;
     21     for(int i=h[x%base];i!=-1;i=pre[i]){
     22         if(val[i]==x&&(y==-1||i<y))y=i;
     23     }
     24     return y;
     25 }
     26 int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
     27 int exgcd(int a,int b,int &x,int &y){
     28     if(b==0){x=1;y=0;return a;}
     29     int tt=exgcd(b,a%b,x,y),xx=x;
     30     x=y;y=xx-a/b*y;return tt;
     31 }
     32 int bsgs(int a,int b,int p){
     33     int m=ceil(sqrt(p*1.0)),D=1,fuckpps=1;
     34     memset(h,-1,sizeof(h));
     35     for(int i=0;i<m;i++)insert(i,fuckpps),fuckpps=1LL*fuckpps*a%p;
     36     for(int i=0,j=-1;i<m;i++){
     37         int x,y,d=exgcd(D,p,x,y);
     38         x=(1LL*x*(b/d)%(p/d)+(p/d))%(p/d);j=get(x);
     39         if(j!=-1)return i*m+j;
     40         D=1LL*D*fuckpps%p;
     41     }
     42     return 0;
     43 }
     44 long long power(int x,int y,int p){
     45     if(y==0)return 1;
     46     if(y==1)return x;
     47     long long tmp=power(x,y/2,p);tmp=tmp*tmp%p;
     48     if(y&1)tmp=tmp*x%p;
     49     return tmp;
     50 }
     51 int tot,f[1000005];
     52 int findg(int pp){
     53     int pps=pp-1;tot=0;
     54     for(int i=2;i*i<=pp-1;i++){
     55         if(pps%i==0){
     56             f[++tot]=i;
     57             while(pps%i==0)pps/=i;
     58         }
     59     }
     60     if(pps!=1)f[++tot]=pps;
     61     for(int i=1;;i++){
     62         int j=1;
     63         for(;j<=tot;j++){
     64             if(power(i,(pp-1)/f[j],pp)==1)break;
     65         }
     66         if(j==tot+1)return i;
     67     }
     68     return 0;
     69 }
     70 long long work2(int A,int B,int p,int cnt){
     71     int pp=power(p,cnt),g=findg(p);
     72     int indB=bsgs(g,B%pp,pp);
     73     int a=A,b=pp-pp/p,c=indB,d=gcd(a,b);
     74     if(c%d)return 0;
     75     return d;
     76 }
     77 long long work3(int A,int B,int p,int cnt){
     78     int a=0;
     79     while(B%p==0)B/=p,a++;
     80     if(a%A)return 0;
     81     return work2(A,B,p,cnt-a)*power(p,a-a/A);
     82 }
     83 int main(){
     84     scanf("%d",&T);
     85     while(T--){
     86         scanf("%d%d%d",&A,&B,&k);k=k*2+1;ans=1;
     87         for(int i=2;i*i<=k;i++){
     88             if(k%i==0){
     89                 int cnt=0,y=1;
     90                 while(k%i==0)k/=i,cnt++,y*=i;
     91                 int d=gcd(B,y);
     92                 if(d==y)ans*=work1(A,B,i,cnt);
     93                 else if(d==1)ans*=work2(A,B,i,cnt);
     94                 else ans*=work3(A,B,i,cnt);
     95             }
     96         }
     97         if(k!=1){
     98             int d=gcd(B,k);
     99             if(d==k)ans*=work1(A,B,k,1);
    100             else if(d==1)ans*=work2(A,B,k,1);
    101         }
    102         printf("%lld
    ",ans);
    103     }
    104     return 0;
    105 }
    View Code
  • 相关阅读:
    Rsync常见运维操作命令
    [图文详解] Sublime Text在Windows/Ubuntu/Mac OSX中配置使用CTags
    Sublime Text : 创建工程
    Sublime Text 插件 & 使用技巧
    如何解决adb devices 端口被占用的问题zz
    Nginx 服务器安装及配置文件详解
    把notepad++设置为系统全局文本默认打开应用
    Ubuntu 下载 & 编译 Android5.1 源码
    同步、更新、下载Android Source & SDK from 国内镜像站
    如何为Linux生成和打上patch
  • 原文地址:https://www.cnblogs.com/longshengblog/p/5773127.html
Copyright © 2011-2022 走看看