2017.10.9 DZY Loves Math V 失败总结

来源:互联网 发布:java reactor设计模式 编辑:程序博客网 时间:2024/06/14 04:31

这种题是不是有什么套路啊。。反正这个系列的题一道都不会。。

据说这个系列是鏼爷出的。。%%%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 1000000007ll 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);}


原创粉丝点击