Processing math: 100%

指数循环节

abab%φ(m)+φ(m)(%m),bφ(m)

我们模m最多只有m种结果,所以根据鸽巢原理,在

a0,a1,...,am(%m)

m+1个数中,一定存在最小r最小s,满足arar+s(%m)r+sm.......(1)

所以序列其实是这样的:

a0,a1,a2,...,ar1,ar,ar+1,...,ar+s1,ar,ar+1,...(%m)

也就是说,从a0ar1不是重复的,但是从ar开始,会循环出现ar,ar+1,...,ar+s1,循环节长度为s......(2)

(1)式得:m|ar+sar,即m|ar(as1)

不妨设m=ar0m,且(a,m)=1......(3)

变成ar0m|ar(as1)......(4)

不妨设r0<r

则由(4)式得m|arr0(as1),即m|arr0+sarr0,所以arr0arr0+s(%m)

又因为m|m,所以arr0arr0+s(%m),所以rr0也满足条件,这与r的最小性矛盾,所以r0=rm=arm

另一方面,在(3)式中,易知(a,as1)=1,所以(ar,as1)=1

m|as1as1(%m)

因为(a,m)=1,根据欧拉定理得aφ(m)1(%m)
所以s|φ(m)

又因为m=arm(a,m)=1,所以φ(m)|φ(m)

所以s|φ(m)

所以结论(2)可描述为:

a0,a1,a2,...,ar1,ar,ar+1,...,ar+φ(m)1,ar,ar+1,...(%m)

a0ar1不是重复的,但是从ar开始,会循环出现ar,ar+1,...,ar+φ(m)1,循环节长度为φ(m)......(5)

因为m=arm,所以φ(m)φ(ar)ar1(a1)r

所以结论(5)又可以描述为:从a0aφ(m)1不是重复的,但是从aφ(m)开始,会循环出现aφ(m),aφ(m)+1,...,aφ(m)+φ(m)1,循环节长度为φ(m)......(5)

所以abab%φ(m)+φ(m)(%m),bφ(m)

另外,如果b<φ(m)直接快速幂就可以了。

 

来看一道例题

题目描述

C同学竟然卡题了!而且还卡在一个不难的题目上。题目是这样的:

定义a^b为a的b次方,并且^是满足右结合的,即a^b^c^d=a^(b^(c^d))。例如,2^3^2=2^(3^2)=2^9=512

现在给定n个数a1,a2,…,an,求a1 ^ a2 ^ … an对p取模的值。

输入格式

输入包括多组数据。

第一行一个整数T,表示数据组数。

接下来每组数据第一行两个整数n,p,第二行n个整数依次描述a1到an。n,p,ai的意义与题目描述一致。

输出格式

    对于每组数据输出一行,包含一个整数,即a1 ^ a2 ^ … an对p取模的值。

输入样例

2

5 13

2 2 2 2 2

3 9

2 3 2

输出样例

3

8

数据范围

对于20%的数据,保证n=2

对于另外30%的数据,保证n≤4,并且a1 ^ a2 ^ … an的位数≤1000,数据组数<=5

对于100%的数据,保证2n≤200<p,ai<10^7,数据组数≤100

 

我们在求快速幂的时候看一下有没有大于等于mod即可

复制代码
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
 
using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b)  for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))
#define SIZE(x) (int(x.size())

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

int gint()
  {
        int res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }
LL gll()
  {
      LL res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }

const int maxn=25;

int n,p,s;
int a[maxn],b[maxn],c[maxn],d[maxn];

int mul(int x)
  {
      int i,res=x;
      for(i=2;i*i<=x;i++)
        if(x%i==0)
          {
              while(x%i==0)x/=i;
              res=res/i*(i-1);
          }
      if(x>1)res=res/x*(x-1);
      return res;
  }

int getpow(int a,int k,int modd)
  {
      LL res=1,x=a,flag=0;
      for(;k;k>>=1)
          {
              if(k&1)
                  {
                      if(res*x>=modd) flag=1;
                      res=res*x%modd;
                    }
                if(k==1)break;
                if(x*x>=modd)flag=1;
                x=x*x%modd;
            }
        if(flag)res+=modd;
      return res;
  }

int main()
  {
      freopen("pow.in","r",stdin);
      freopen("pow.out","w",stdout);
      int i,j,T=gint();
      while(T--)
        {
            n=gint();p=gint();mmst(a,0);mmst(b,0);mmst(c,0);mmst(d,0);
            re(i,1,n)a[i]=gint();
            s=0;for(int t=p;t!=1;t=mul(t))b[++s]=t;
            re(j,1,s)
                  {
                      c[j]=a[n]%b[j];
                      if(a[n]>=b[j])c[j]+=b[j];
                    }
            red(i,n-1,1)
              {
                  re(j,1,s)d[j]=getpow(a[i],c[j+1],b[j]);
                  re(j,1,s)c[j]=d[j];
              }
            PF("%d\n",c[1]%p);
        }
      return 0;
  }
View Code
复制代码

 

posted @   maijing  阅读(2944)  评论(3编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
· 【译】.NET 升级助手现在支持升级到集中式包管理
· 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
· Tinyfox 发生重大改版
点击右上角即可分享
微信分享提示