数论专场
Strange Limit
题目大意
给你 \(p\) 和 \(m\) ,求 \(p^{p^{p^{p……}}}\ mod\ m!\)
思路
有 \(n\) 个 \(p\), \(n\) 为无穷大,也就是递归里套一个指数循环节,然后因为 \(n\) 趋向于无限大,那么当前要 \(mod\) 的 \(x\) \(\mu (\mu (\mu (m)))\),也在一直缩小。
如果当 \(p\ mod\ x=0\) 的时候,就是返回个 \(p^p\ mod\ x\),再往上就是 \(0\) 的几次方了,已经没有影响了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int p,m,A[15]={1};
int euler(int x)
{
int ans=x;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
ans-=ans/i;
while(x%i==0)
x/=i;
}
}
if(x>1)
ans-=ans/x;
return ans;
}
ll qpow(ll a,ll b,ll c)
{
ll ans=1;
if(a>=c)
a=a%c+c;
while(b)
{
if(b&1)
{
ans*=a;
if(ans>=c)
ans=ans%c+c;
}
a*=a;
if(a>=c)
a=a%c+c;
b>>=1;
}
return ans;
}
ll ap(int x)
{
if(p%x==0)
return qpow(p,p,x);
return qpow(p,ap(euler(x)),x);
}
int main()
{
freopen("limit.in", "r", stdin);
freopen("limit.out", "w", stdout);
for(int i=1;i<=12;i++)
A[i]=A[i-1]*i;
cin>>p>>m;
printf("%lld\n",ap(A[m])%A[m]);
return 0;
}
GCD Determinant(SP4195)
题目大意
有 \(n\) 个正整数 \(a_i\) 和一个 \(n\times n\) 的矩阵,矩阵中 \(i\) 行 \(j\) 列的元素为 \(gcd(a_i,a_j)\),求矩阵的行列式。
思路
结论为 \(\phi a_1\times \phi a_2\times \phi a_3 \times ……\times \phi a_n\)。
(可以先暴力算出矩阵的行列式,然后消掉)
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
ll solve(int x)
{
ll ans=x;
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
ans=ans*(i-1)/i;
while(x%i==0)
x/=i;
}
}
if(x>1)
ans=ans*(x-1)/x;
return ans%mod;
}
int n;
int main()
{
while(cin>>n)
{
ll ans=1;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
ans=ans*solve(x)%mod;
}
cout<<ans<<'\n';
}
return 0;
}
Remainders Game(CF687B)
题目大意
给定 \(n\) 个正整数 \(c_i\) 和 \(k\),假设你知道一个数 \(x\),问能否从 \(x\ mod\ c_i\) 推出 \(x\ mod\ k\)。
思路
用中国剩余定理,所以我们知道只要 \(c_i\) 中包含了所有的 \(k\) 的质因数就可以推出,但把每个数全部分解质因数明显不可以,其实只要 \(c_i\) 的最小公倍数 \(mod\ k=0\) 就可以了,注意每次还要 \(mod\ k\)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
int n,k;
ll add=1;
int main()
{
n=read(),k=read();
for(int i=1;i<=n;i++)
{
ll x=read();
add=add*x/__gcd(add,x)%k;
}
if(add%k==0)
puts("Yes");
else
puts("No");
return 0;
}
总结
上午是请了南京大学的教授讲数论,分了三小节课讲,第一节的全部和第二节的一部分能听懂,从中国剩余定理讲到一堆东西,再讲到群和矩阵。
标签:ch,return,数论,ll,cd,int,ans,mod From: https://www.cnblogs.com/noipwen/p/17997217