<8/5>集训日记

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

费马小定理内容:假如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;

}

 

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

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值