对于本题建议先观看洛谷 P3811 【模板】模意义下的乘法逆元 、 乘法逆元 - OI Wiki 和 洛谷 P3811 【模板】模意义下的乘法逆元-CSDN博客 的讲解。
题目描述
给定 𝑛 个正整数 𝑎𝑖 ,求它们在模 𝑝 意义下的乘法逆元。
由于输出太多不好,所以将会给定常数 𝑘,你要输出的答案为:
答案对 𝑝 取模。
输入格式
第一行三个正整数 𝑛,𝑝,𝑘意义如题目描述。
第二行 𝑛 个正整数 𝑎𝑖是你要求逆元的数。
输出格式
输出一行一个整数,表示答案。
输入输出样例
输入 #1复制
6 233 42 1 4 2 8 5 7
输出 #1复制
91
说明/提示
对于 30% 的数据,1≤𝑛≤1e5
对于 100% 数据,1≤𝑛≤5×1e6,2≤𝑘<𝑝≤1e9,1≤𝑎𝑖<𝑝,保证 𝑝 为质数。
提示:本题时间限制较为严格,请注意使用较快的 IO 方式。
看了以上讲解,应该知道答题思路了;
我们可以根据以前的思路写出代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,p,k,fac[5000005],inv[5000005],ans,x[5000005];
int binpow(int a,int b)
{
int res=1;
while(b)
{
if(b&1)
{
res*=a;
res%=p;
}
a*=a;
a%=p;
b>>=1;
}
return res;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>p>>k;
int sb=k;
fac[0]=1;
for(int i=1;i<=n;++i)
{
cin>>x[i];
}
for(int i=1;i<=n;++i)
{
fac[i]=fac[i-1]*x[i];
fac[i]%=p;
}
inv[n]=binpow(fac[n],p-2);
for(int i=n-1;i>=1;--i)
{
inv[i]=inv[i+1]*x[i+1]%p;
}
for(int i=1;i<=n;++i)
{
ans+=fac[i-1]*inv[i]%p*k;
ans%=p;
k*=sb;
k%=p;
}
cout<<ans;
return 0;
}
但是你会发现,这样的代码依然会TLE,你可能就非常的疑惑,但是如果你在读一遍题,你会发现,有一句话是这么写的:提示:本题时间限制较为严格,请注意使用较快的 IO 方式。
所以这个题目读入要使用快读,输出使用printf或cout快速优化,(最好使用printf);
所以我把我的快读模版给大家:
inline int read(){
int n=0,x=1;char c;
for(c=getchar();c<'0'||c>'9';c=getchar())
if(c=='-')x=-1;else x=1;
for(;c>='0'&&c<='9';c=getchar())
n=(n<<3)+(n<<1)-'0'+c;
return x*n;
}
这样我们就可以写出AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int n=0,x=1;char c;
for(c=getchar();c<'0'||c>'9';c=getchar())
if(c=='-')x=-1;else x=1;
for(;c>='0'&&c<='9';c=getchar())
n=(n<<3)+(n<<1)-'0'+c;
return x*n;
}
int n,p,k,fac[5000005],inv[5000005],ans,x[5000005];
int binpow(int a,int b)
{
int res=1;
while(b)
{
if(b&1)
{
res*=a;
res%=p;
}
a*=a;
a%=p;
b>>=1;
}
return res;
}
signed main()
{
//ios::sync_with_stdio(0);使用getchar()和printf最好关闭cin快速优化
//cin.tie(0);cout.tie(0);
n=read(),p=read(),k=read();
int sb=k;
fac[0]=1;
for(int i=1;i<=n;++i)
{
x[i]=read();
}
for(int i=1;i<=n;++i)
{
fac[i]=fac[i-1]*x[i];
fac[i]%=p;
}
inv[n]=binpow(fac[n],p-2);
for(int i=n-1;i>=1;--i)
{
inv[i]=inv[i+1]*x[i+1]%p;
}
for(int i=1;i<=n;++i)
{
ans+=fac[i-1]*inv[i]%p*k;
ans%=p;
k*=sb;
k%=p;
}
printf("%lld",ans);//cout<<ans;
return 0;
}
对于读入和输出(getchar()/putchar()>scanf()/printf()>cin/cout(即使有cin,cout快速优化))
像这种比较肮脏的题目 洛谷 也是比较多的大家要注意!!!