B Basic Gcd Problem
打表找规律,通过观察我们可以发现,答案为 c^n的质因子个数,例如 12 可以质因子分解为 2,2,3,因此其答案为 c^3。
#include
#include
using namespace std;
int gcd(int x,int y)
{
return y>0?gcd(y,x%y):x;
}
int fc(int x)
{
if(x==1)
return 1;
int ma=0;
for(int i=1;i<x;++i)
{
ma=max(ma,fc(gcd(x,i)));
}
return 3*ma;
}
int main()
{
for(int i=1;i<=20;++i)
printf("%d=%d\n",i,fc(i));
return 0;
}
#include
#include
#include
using namespace std;
const int maxn=1e6+5;
const long long mod=1e9+7;
long long su[maxn],cnt;
bool isprime[maxn];
int T;
long long n,c;
void prime()
{
cnt=1;
memset(isprime,1,sizeof(isprime));
isprime[0]=isprime[1]=0;
for(long long i=2;i<=maxn;i++)
{
if(isprime[i])
su[cnt++]=i;
for(long long j=1;j<cnt&&su[j]*i<=maxn;j++)
{
isprime[su[j]*i]=0;
}
}
}
long long getprimefactor(long long nn)
{
int cas=0;
for(int i=1;i<cnt&&su[i]*su[i]<=nn;++i)
{
while(nn%su[i]==0)
{
cas++;
nn/=su[i];
}
}
if(nn>1)
cas++;
return cas;
}
long long quickpow(long long a,long long b)
{
long long s=1;
while(b>0)
{
if(b&1)
s=(s*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return s;
}
int main()
{
prime();
scanf("%d",&T);
while(T--)
{
scanf("%lld %lld",&n,&c);
long long a=getprimefactor(n);
printf("%lld\n",quickpow(c,a));
}
return 0;
}
F Finding the Order
这题只要把所有情况找出来,就可以发现,如果最长的边为 AD或者BC,那就是 AB//CD。如果最长的边为 AC或者BD,那就是 AB//DC。
#include
#include
using namespace std;
int T;
int a,b,c,d;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d",&a,&b,&c,&d);
int ma=max(max(a,b),max(c,d));
if(ma==a||ma==d)
puts("AB//DC");
else
puts("AB//CD");
}
return 0;
}
H Harder Gcd Problem
贪心+思维,先把所有素数*2>n的排除掉,在从后往前找每一个质因数,顺次匹配,遇到 2*p 先跳过,如果可以匹配的数量为奇数,最后的数与 2*p匹配。偶数则 2*p 不在这里匹配(可以留到前面去匹配)。
#include
#include
#include
using namespace std;
const int maxn=2e5+5;
bool vis[maxn];
bool isprime[maxn];
int su[maxn];
int T,n;
int ans[maxn];
int cnt,tot;
void prime()
{
cnt=1;
memset(isprime,1,sizeof(isprime));
isprime[0]=isprime[1]=0;
for(long long i=2;i<=maxn;i++)
{
if(isprime[i])
su[cnt++]=i;
for(long long j=1;j<cnt&&su[j]*i<=maxn;j++)
{
isprime[su[j]*i]=0;
}
}
}
void init()
{
memset(vis,0,sizeof(vis));
tot=0;
}
int main()
{
prime();
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
int r;
for(int i=1;i<cnt&&su[i]<=n;++i)
{
if(su[i]*2>n)
vis[su[i]]=1;
else
{
r=i;
}
}
for(int i=r;i>=1;i--)
{
int s=0;
for(int j=1;j*su[i]<=n;++j)
{
if(j==2||vis[j*su[i]])
continue;
vis[j*su[i]]=1;
ans[++tot]=j*su[i];
s++;
}
if(s%2==1&&!vis[2*su[i]])
{
ans[++tot]=2*su[i];
vis[2*su[i]]=1;
}
}
printf("%d\n",tot/2);
for(int i=1;i<=tot-1;i+=2)
printf("%d %d\n",ans[i],ans[i+1]);
}
return 0;
}