T1
给定一个n和k,求可爱数字的个数
其中可爱的数字满足
对于实数 , 表示x的小数部分。
QwQ这道应该是全场最难的题了
题解:观察一下题目中的那个式子,不难看出其实有点像把n转成k进制,那么,如果一个数转成k进制之后,是非周期的(就是依次从最后移动到最前,所有的数都不一样),那么一定有一个数满足这个式子,也就是最小的那个
并且….k进制下最小的循环节d一定是满足
有一个惊人的发现:我们将非周期的求出来…..就能发现…
其中长度为n的非循环节的数的个数可以通过dp来求
首先呢,我们考虑,我们求非循环节的个数,实际上就是总数减去所有有循环节的个数
那么总数就是
那么有循环节的呢?
我们考虑能够成循环节的,一定是i的因数,且每一个节循环节内部没有循环节,否则就会重复计数,所以我们就是对于每一个 就可以
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const ll mod = 1e9+7;
ll n,k,f[1000010];
ll mul[1000010];
ll qsm(ll i,ll j)
{
ll ans=1;
while (j)
{
if (j&1) ans=ans*i%mod;
i=i*i%mod;
j>>=1;
}
return ans;
}
ll cnt;
int main()
{
cin>>n>>k;
for (ll i=1;i*i<=n;i++)
{
if (n%i==0)
{
mul[++cnt]=i;
if (i*i<n) mul[++cnt]=n/i;
}
}
sort(mul+1,mul+1+cnt);
for (ll i=1;i<=cnt;i++)
{
f[i]=qsm(k,mul[i]);
for (ll j=1;j<=i-1;j++)
if (mul[i]%mul[j]==0) f[i]=(f[i]-f[j]+mod)%mod;
}
printf("%lld",f[cnt]*qsm(n,mod-2)%mod);
return 0;
}
T2
求 的值
其中
保证p是质数
十分简单,根据费马小定理,我们可以直接把 然后再算快速幂就好
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
ll a,b,c,p;
ll qsm(ll i,ll j,ll mod)
{
ll ans=1;
i=i%mod;
while (j)
{
if (j&1) ans=ans*i%mod;
i=i*i%mod;
j>>=1;
}
return ans;
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
cin>>a>>b>>c>>p;
//cout<<qsm(a,b,c)<<endl;
ll tmp = qsm(b,c,p-1);
cout<<qsm(a,tmp,p);
return 0;
}
T3
设
表示n的所有正约数的平方和,输入n和
,你只需要输出
解法:我们考虑,对于每个约数i,我们其实就是求的
那么 这个东西可以整除分块
同时
对于一段区间 ,直接用 就行,注意取膜的一些小细节
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
ll ans;
ll n;
ll p;
ll inv;
ll qsm(ll i,ll j)
{
ll ans=1;
while (j)
{
if (j&1) ans=ans*i%p;
i=i*i%p;
j>>=1;
}
return ans;
}
ll count(ll x)
{
x=x%p;
return x*(x+1)%p*(2*x+1)%p*inv%p;
}
int main()
{
freopen("sos.in","r",stdin);
freopen("sos.out","w",stdout);
cin>>n>>p;
inv = qsm(6,p-2);
for (ll i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
ans=(ans+(n/i)*((count(j)-count(i-1)+p)%p)%p)%p;
//cout<<i<<" "<<j<<" "<<ans<<endl;
}
cout<<ans;
return 0;
}