<85>集训日记

xiaoxiao2021-02-28  119

先是一道有关费马小定理的题。

费马小定理内容:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)1(mod p),即:假如a是整数,p是质数,且a,p互质,那么a(p-1)次方模p的余数恒等于1

题目:Codeforces Round #338(Div. 2) D. Multipliers

题意很简明,给你一个数的所有质因数,然后让你求出这个数所有因数的乘积。

对于每个质因子,对答案的贡献为p^(d[p] *(d[p]-1) \ 2 * d[s])

d[p]表示p的因子数量,d[s]表示s这个数的因子数量

数量可以由因子数量定理求得,d[s] =(a1+1)(a2+1)...(an+1)a1.a2.a3表示s的质因子的次数。

但是由于指数可能很大,所以我们就需要使用费马小定理就好了

但是又有除2的操作,mod-1有不是质数,不存在逆元,所以先对2mod-1)取模。

代码如下:

#include<bits/stdc++.h>

using namespace std;

#define maxn 200005

long long mod = 1e9+7;

long long mod2 = 2LL*(mod - 1);

long long quickpow(long long a,long longb,long long c)

{

   long long ans = 1;

   while(b)

    {

       if(b&1)ans = ans * a % c;

       a = a * a % c;

       b>>=1;

    }

   return ans;

}

int cnt[maxn];

int p[maxn];

int vis[maxn];

int main()

{

   int n;

   scanf("%d",&n);

   for(int i=1;i<=n;i++)

    {

       scanf("%d",&p[i]);

       cnt[p[i]]++;//记录每个数的个数

    }

   long long tot = 1;

   for(int i=1;i<=n;i++)

    {

       if(vis[p[i]])continue;//跳出此次循环

       vis[p[i]]=1;

       tot = tot*(cnt[p[i]]+1)%mod2;//求因子数= (a1+1)(a2+1)...(an+1)a1.a2.a3表示质因子的次数

    }

   memset(vis,0,sizeof(vis));

   long long ans = 1;

   for(int i=1;i<=n;i++)

    {

       if(vis[p[i]])continue;

       vis[p[i]]=1;

       ans=ans*quickpow(p[i],(tot*cnt[p[i]]/2)%mod2,mod)%mod;//每个数的贡献,费马小定理

    }

   cout<<ans<<endl;

}

 

家人在医院住院,需要去医院陪床,所以就写这些吧。

以上

转载请注明原文地址: https://www.6miu.com/read-36846.html

最新回复(0)