zoukankan      html  css  js  c++  java
  • HDU4335 What is N? [数论(欧拉函数)]

      这就是大神口中的简单题,我的数论简直烂到不行,这些数学出身的家伙何必出这些恶心的数学题来难为我们呢。。

      用到一个公式 A^x%P=(A^(x%phi(P)+phi[P]))%P (x>=phi[C]),phi[C]表示欧拉函数。

      注意条件是x>=phi[C],但这题的x是增长很快的,很快就能满足这个条件,所以x<phi[C]这部分暴力即可。

      接着继续暴力求x%phi[C]!=0的情况,很快就会出现x%phi[C]==0,并且之后一直都会满足,题目转化为求A^phi[P]%P==b,根据鸽巢原理,一定会出现长度为P循环节,于是统计循环节内满足条件的数的个数,再乘以循环节个数,然后在暴力统计一下多余长度内有多少个数满足条件即可。

      一个很大的trick就是结果会超LongLong,达到2^64,这里需要特判。。

     1 #include <string.h>
     2 #include <stdio.h>
     3 #define MAXN 100005
     4 typedef unsigned long long ULL;
     5 int cas;
     6 ULL m,ans,n,fac,tot,b,p;
     7 ULL phi[MAXN],mod[MAXN];
     8 //A^x%P=A^(x%phi(P)+phi[P])%P (x>=phi[C])
     9 void init(){
    10     for(int i=1;i<MAXN;i++)phi[i]=i;
    11     for(int i=2;i<MAXN;i+=2)phi[i]/=2;
    12     for(int i=3;i<MAXN;i+=2)if(phi[i]==i){
    13         for(int j=i;j<MAXN;j+=i)phi[j]=phi[j]/i*(i-1);
    14     }
    15 }
    16 ULL pow(ULL a,ULL x){
    17     ULL ret=1;
    18     for(ULL tmp=a;x;x>>=1){
    19         if(x&1){
    20             ret*=tmp;
    21             if(ret>=p)ret%=p;
    22         }
    23         tmp*=tmp;
    24         if(tmp>=p)tmp%=p;
    25     }
    26     return ret;
    27 }
    28 int main(){
    29     //freopen("test.in","r",stdin);
    30     init();
    31     scanf("%d",&cas);
    32     for(int ca=1;ca<=cas;ca++){
    33         scanf("%I64u%I64u%I64u\n",&b,&p,&m);
    34         //TRICK! p==1&&c==0&&m=2^64-1 溢出
    35         if(m==18446744073709551615ULL&&p==1ULL&&b==0ULL){
    36             printf("Case #%d: 18446744073709551616\n",ca);
    37             continue;
    38         }
    39         ans=n=tot=0,fac=1;
    40         //step1;n!<=phi[p]
    41         for(;n<=m&&fac<phi[p];n++,fac*=n)
    42             if(pow(n,fac)==b)ans++;
    43         //step2:n!%phi[p]!=0
    44         fac%=phi[p];
    45         for(;n<=m&&fac;n++,fac=fac*n%phi[p])
    46             if(pow(n,fac+phi[p])==b)ans++;
    47         //step3:n!%phi[p]==0
    48         if(n<=m){
    49             ULL rel=m-n+1;
    50             for(ULL i=0;i<p;i++){
    51                 mod[i]=pow(n+i,phi[p]);
    52                 tot+=(mod[i]==b?1:0);
    53             }
    54             ans+=(ULL)tot*(rel/p);
    55             rel%=p;
    56             for(ULL i=0;i<rel;i++){
    57                 ans+=(mod[i]==b?1:0);
    58             }
    59         }
    60         printf("Case #%d: %I64u\n",ca,ans);
    61     }
    62 }
  • 相关阅读:
    c# 遮罩
    判断当前task中的运行的activity是否为当前应用
    Chrome+SwitchySharp+myentunnel+SSH
    vps
    系统制作
    vs2010 mfc
    android ndk
    乐 Phone刷机教程(全过程)
    mysql 保留字 冲突
    mysql 存储过程
  • 原文地址:https://www.cnblogs.com/swm8023/p/2661267.html
Copyright © 2011-2022 走看看