『专题』指数循环节问题

转载链接:http://blog.csdn.net/acdreamers/article/details/8236942

个人感觉:
最近有点忙,今天才把几道指数循环节题目给刷完.而且过程有点坑,- -在nefuOJ上交题一旦有重定向都给WA了…我搞了一个下午才发现的,我就说我写得没错,略坑…浪费了好多时间.
基本的东西我就不说了,还缺一题是zju的,但OJ崩了没去刷,我只上我做了的代码吧。

Problem 1759 Super A^B mod C

分析:敲门题,难度不高

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e6+10;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

 ll A;
 char B[maxn];
 ll C;
 ll phi;

 ll ouler(ll c)
 {
     ll res=c;
     for(ll i=2;i*i<=c;i++)
     {
         if(c%i==0)
         {
             res=res/i*(i-1);
             while(c%i==0) c/=i;
         }
     }
     if(c>1) res=res/c*(c-1);

     return res;
 }

 ll getZ()
 {
     ll res=0;
     for(int i=0;B[i]!='\0';i++)
     {
         res=res*10+B[i]-'0';
         res%=phi;
     }

     return res+phi;
 }
 ll qmod(ll a,ll b)
 {
     ll res=1;
     while(b)
     {
        if(b&1)res=(res*a)%C;
        a=(a*a)%C;
        b>>=1;
     }
     return res%C;
 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    while(scanf("%I64d%s%I64d",&A,B,&C)!=EOF)
    {
        phi=ouler(C);
        //cout<<phi<<endl;
        ll z=getZ();
        //cout<<"--->"<<z<<endl;

        printf("%I64d\n",qmod(A%C,z));

    }

    return 0;
}

B.Calculation
分析:一丢丢的思维深度,开始理解指循环节!,注意如果你忽略了**(B>=phi§)这个条件,必定让你WA成狗,这个条件不能忽视,**
虽然第一题可以这样但是只是数据有点水,我也不太会举这个样例,

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

int T;
ll n,m;
 ll eulor(ll c)
 {
     ll res=c;
     for(ll i=2;i*i<=c;i++)
     {
         if(c%i==0)
         {
             res=res/i*(i-1);
             while(c%i==0)c/=i;
         }
     }

     if(c>1) res=res/c*(c-1);
     return res;
 }


 ll qmod(ll a,ll b,ll M)
 {
     ll res=1;
     while(b)
     {
         if(b&1)
         {
             res=res*a;
             if(res>=M) res=res%M+M;
         }
         a=(a*a);
         if(a>=M){a=a%M+M;}
         b>>=1;
     }
     return res;
 }
ll f(ll n,ll m)
{
    if(n<10) return n;
    ll p=f(n/10,eulor(m));
    return qmod(n%10,p,m);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&n,&m);
        printf("%I64d\n",f(n,m)%m);
    }
    return 0;
}

D:Remainder Calculator

分析:千万别留重定向,肯定会wa了… 你做了第2题这个就很深刻了.

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

ll n,m;
ll a[105];
int T;
bool f;

ll eulor(ll c)
{
    ll res=c;
    for(ll i=2;i*i<=c;i++)
    {
        if(c%i==0)
        {
            res=res/i*(i-1);
            while(c%i==0)c/=i;
        }
    }
    if(c>1) res=res/c*(c-1);
    return res;
}

ll qmod(ll a,ll b,ll M)
{
    ll res=1;
    while(b)
    {
        if(b&1)
        {
            res=res*a;
            if(res>=M) f=true;
            if(f)res%=M;
        }
        a=(a*a);
        if(a>=M) f=true;
        if(f) a%=M;
        b>>=1;
    }
    return res;
}
ll  solve(int step,ll m)
{

    if(step==n)
    {
        ll res=1;

        f=false;
        for(ll i=1;i<=a[step];i++)
        {
            res=(res*i);
            if(res>=m) f=true;
            if(f) res%=m;
        }
        if(f) return res%m+m;
        return res;
    }

    if(a[step]>=m)
    {
        return m;
    }

    ll z=solve(step+1,eulor(m));

    ll d=1;
    for(ll i=1;i<=a[step];i++)
    {
           d*=i;
           if(d>=m)f=true;
           if(f)d%=m;
    }

    ll res=qmod(d,z,m);
    if(f) return res%m+m;
    return res;
}
int main()
{

   scanf("%d",&T);
   while(T--)
   {
       cin>>n>>m;

       for(int i=1;i<=n;i++)cin>>a[i];

       if(m==1)
       {
           printf("0\n");
           continue;
       }

       cout<<(solve(1,m)%m)<<endl;
   }


    return 0;
}

E:What is N

分析:做完之后你会发现,这题就水题了.

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }
 int T;
 ull b,p,M;

 ull phi(ull c)
 {
     ull res=c;
     for(ull i=2;i*i<=c;i++)
     {
         if(c%i==0)
         {
             res=res/i*(i-1);
             while(c%i==0) c/=i;
         }
     }
     if(c>1) res=res/c*(c-1);
     return res;
 }
 ull qmod(ull a,ull b,ull M)
 {
     ull res=1;
     while(b)
     {
         if(b&1)res=(res*a)%M;
         a=(a*a)%M;
         b>>=1;
     }
     return res%M;
 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        scanf("%I64u%I64u%I64u",&b,&p,&M);
        if(b==0&&p==1&&M == 18446744073709551615ull)
        {
           printf("Case #%d: 18446744073709551616\n",cas);
           continue;
        }

        ull ans=0;
        ull mod=phi(p);
        if(b==0)ans++;
        bool flag=false;
        ull z=1;
        ull i;
        for(i=1;i<=M;i++)
        {
              z=z*i;

              if(z>=mod)
              {
                  z%=mod;
                  flag=true;

                  if(z==0)break;
              }

              if(flag)
              {
                  if(qmod(i,z+mod,p)==b) ans++;
              }
              else
              {
                   if(qmod(i,z,p)==b) ans++;
              }
        }
        for(ull k=0;i<=M&&k<p;i++,k++)
        {
            if(qmod(i,mod,p)==b)
            {
               ans+=1+(M-i)/p;
            }
        }


        printf("Case #%d: %I64u\n",cas,ans);


    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值