2017.10.9 DZY Loves Math V 失败总结
2017-10-09 21:17
239 查看
这种题是不是有什么套路啊。。反正这个系列的题一道都不会。。
据说这个系列是鏼爷出的。。%%%ORZORZ
这个phi似乎很多题都用了他积性函数的性质。。都是分素数分素数,统计统计,,然后加着加着就变成乘了。。
由于不同素数的影响是独立的。。所以可以用乘法原理
所以ans=第一个素数的贡献*第二个素数的贡献*....
统计一个素数的贡献时每一个ai拆出的素数情况也是独立的,,所以 一个素数的贡献=a1拆的贡献*a2拆的贡献+a3拆的贡献+...
单个a的贡献就是一组累乘了。。。(如果不直观的话可以把所有数都拆成几个1来表示组合关系,,然后发现一组里的1是可以合并的,答案不变)
由于ai==1e7 所以多次出现的素数一定<sqrt(1e7)
剩下的还有出现一次的,单独统计即可
码(又丑又慢):
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define P 1000000007
ll n,p[100005],he[10000005],ans=1,i,j,k,geshu,ni,su[10000005],tot,a[100005];
ll ksm(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2)ans=(ans*a)%P;
b/=2;
a=(a*a)%P;
}
return ans;
}
void eular(ll n)
{
ll i,j;
for(i=2;i<=n;i++)
{
if(!he[i])
{
su[++tot]=i;
}
for(j=1;j<=tot&&su[j]*i<=n;j++)
{
he[su[j]*i]=1;
if(i%su[j]==0)
{
break;
}
}
}
}
int main()
{
scanf("%lld",&n);
eular(5000);
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
for(i=1;i<=tot;i++)
{//cout<<i<<" "<<tot<<" ";
ll o=su[i];
ll lin=1;
p[0]=1;
he[0]=1;
ni=ksm(o,P-2);
for(j=1;j<=30;j++)
{
p[j]=(p[j-1]*o)%P;
he[j]=(he[j-1]+p[j])%P;
}
for(j=1;j<=n;j++)
{
geshu=0;
while(a[j]%o==0)
{
a[j]/=o;
geshu++;
}
lin=lin*he[geshu]%P;
}
if(lin>1)ans=(ans*((lin-1)%P*(o-1)%P*ni%P+1))%P;
}
tot=0;
memset(he,0,sizeof(he));
for(i=1;i<=n;i++)
{
if(a[i]>1)
{
if(he[a[i]]==0)su[++tot]=a[i];
he[a[i]]++;
}
}
for(i=1;i<=tot;i++)
{
ans=ans*((ksm(su[i]+1,he[su[i]])-1)*(su[i]-1)%P*ksm(su[i],P-2)%P+1)%P;
}
printf("%lld",ans);
}
据说这个系列是鏼爷出的。。%%%ORZORZ
这个phi似乎很多题都用了他积性函数的性质。。都是分素数分素数,统计统计,,然后加着加着就变成乘了。。
由于不同素数的影响是独立的。。所以可以用乘法原理
所以ans=第一个素数的贡献*第二个素数的贡献*....
统计一个素数的贡献时每一个ai拆出的素数情况也是独立的,,所以 一个素数的贡献=a1拆的贡献*a2拆的贡献+a3拆的贡献+...
单个a的贡献就是一组累乘了。。。(如果不直观的话可以把所有数都拆成几个1来表示组合关系,,然后发现一组里的1是可以合并的,答案不变)
由于ai==1e7 所以多次出现的素数一定<sqrt(1e7)
剩下的还有出现一次的,单独统计即可
码(又丑又慢):
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define P 1000000007
ll n,p[100005],he[10000005],ans=1,i,j,k,geshu,ni,su[10000005],tot,a[100005];
ll ksm(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2)ans=(ans*a)%P;
b/=2;
a=(a*a)%P;
}
return ans;
}
void eular(ll n)
{
ll i,j;
for(i=2;i<=n;i++)
{
if(!he[i])
{
su[++tot]=i;
}
for(j=1;j<=tot&&su[j]*i<=n;j++)
{
he[su[j]*i]=1;
if(i%su[j]==0)
{
break;
}
}
}
}
int main()
{
scanf("%lld",&n);
eular(5000);
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
for(i=1;i<=tot;i++)
{//cout<<i<<" "<<tot<<" ";
ll o=su[i];
ll lin=1;
p[0]=1;
he[0]=1;
ni=ksm(o,P-2);
for(j=1;j<=30;j++)
{
p[j]=(p[j-1]*o)%P;
he[j]=(he[j-1]+p[j])%P;
}
for(j=1;j<=n;j++)
{
geshu=0;
while(a[j]%o==0)
{
a[j]/=o;
geshu++;
}
lin=lin*he[geshu]%P;
}
if(lin>1)ans=(ans*((lin-1)%P*(o-1)%P*ni%P+1))%P;
}
tot=0;
memset(he,0,sizeof(he));
for(i=1;i<=n;i++)
{
if(a[i]>1)
{
if(he[a[i]]==0)su[++tot]=a[i];
he[a[i]]++;
}
}
for(i=1;i<=tot;i++)
{
ans=ans*((ksm(su[i]+1,he[su[i]])-1)*(su[i]-1)%P*ksm(su[i],P-2)%P+1)%P;
}
printf("%lld",ans);
}
相关文章推荐
- 2017.10.9 DZY Loves Math VI 失败总结
- 2017.9.5 DZY Loves Math 失败总结
- Bzoj3481 DZY Loves Math III
- BZOJ 3309 DZY Loves Math
- BZOJ 3309 DZY Loves Math 莫比乌斯反演
- BZOJ3739: DZY loves math VIII
- [BZOJ3512]DZY Loves Math IV 杜教筛+记忆化搜索
- bzoj3560 DZY Loves Math V 数论
- [BZOJ3512] DZY Loves Math IV -- 杜教筛,搜索
- bzoj3309 DZY Loves Math(线性筛+反演)
- BZOJ3309: DZY Loves Math
- bzoj 3309 DZY Loves Math
- 【BZOJ3309】DZY Loves Math
- bzoj 3512 DZY Loves Math IV
- 【线性筛】【bzoj 3309】: DZY Loves Math
- 2017.10.9 找相同字符 失败总结
- bzoj 3309: DZY Loves Math
- bzoj3512 DZY Loves Math IV
- BZOJ 3309: DZY Loves Math
- BZOJ3309 :DZY Loves Math(莫比乌斯反演)