博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 3561: DZY Loves Math VI
阅读量:5094 次
发布时间:2019-06-13

本文共 2464 字,大约阅读时间需要 8 分钟。

3561: DZY Loves Math VI

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 489  Solved: 323
[][][]

Description

给定正整数n,m。求
 
 

Input

一行两个整数n,m。

Output

一个整数,为答案模1000000007后的值。

Sample Input

5 4

Sample Output

424

HINT

 

数据规模:

1<=n,m<=500000,共有3组数据。

 

Source

 

常年不做数论了,略感生疏。。。

首先和gcd有关的可以枚举公因数:

ANS=∑(d= 1 to n) d^d *f(n/d,m/d,d)。

其中f(x,y,z)表示1<=i<=x,1<=j<=y中gcd(i,j)==1的(xy)^z之和。

f直接求不好求,我们考虑反演得到f。

设g(x,y,z)为1<=i<=x,1<=j<=y的(xy)^z之和。

拆括号可以得到:g(x,y,z)=(∑ i^z)*(∑ j^z)。

g可以用f表示: g(x,y,z)=∑f(x/i,y/i,z)* i^(2*z)。

然后用g反演得f: f(x,y,z)=∑g(x/i,y/i,z) * i^(2*z) * μ(i)

 

总式子太长了,懒得打上了。。。

总之这个题最后的式子没法用一般的数论dark技巧优化,只能暴力求。。

也就是外层d枚举,d,n/d,m/d 确定了之后内层也是暴力做。。

(所以我也不知道我怎么没有TLE)

(而且感觉我内层的预处理既浪费了运行时间又显得很蠢hhh)

/**************************************************************    Problem: 3561    User: JYYHH    Language: C++    Result: Accepted    Time:7860 ms    Memory:11936 kb****************************************************************/ #include
#define ll long long#define ha 1000000007#define maxn 500005using namespace std;ll n,m,k,ans=0,ci[maxn],qz[maxn];int miu[maxn],t=0,zs[maxn/5];bool v[maxn]; inline ll ksm(ll x,ll y){ ll an=1; for(;y;y>>=1,x=x*x%ha) if(y&1) an=an*x%ha; return an;} inline void init(){ miu[1]=1; for(int i=2;i<=500000;i++){ if(!v[i]) zs[++t]=i,miu[i]=-1; for(int j=1,u;j<=t&&(u=zs[j]*i)<=500000;j++){ v[u]=1; if(!(i%zs[j])) break; miu[u]=-miu[i]; } }// for(int i=1;i<=500000;i++) miu[i]+=miu[i-1];} inline ll mul(ll x,ll y){ x*=y; if(x>=ha) x-=x/ha*ha; return x;} inline ll f(ll x,ll y,ll z){// printf("round %lld %lld %lld:\n"); ll an=0,now,a1,a2; qz[1]=1,ci[1]=1; for(int i=2;i<=z;i++){ ci[i]=ksm(i,y); qz[i]=ci[i]*ci[i]; if(qz[i]>=ha) qz[i]-=qz[i]/ha*ha; qz[i]*=miu[i]; if(qz[i]<0) qz[i]+=ha; ci[i]+=ci[i-1]; if(ci[i]>=ha) ci[i]-=ha; qz[i]+=qz[i-1]; if(qz[i]>=ha) qz[i]-=ha; } for(int i=1,j;i<=x;i=j+1){ a1=x/i,a2=z/i; j=min(x/a1,z/a2); now=qz[j]-qz[i-1]+ha; if(now>=ha) now-=ha; an+=mul(mul(ci[a1],ci[a2]),now); if(an>=ha) an-=ha; } return an;} int main(){ init(); scanf("%lld%lld",&n,&m); if(n>m) swap(n,m); for(int i=1;i<=n;i++){ ans+=ksm(i,i)*f(n/i,i,m/i); if(ans>=ha) ans-=ans/ha*ha; } printf("%lld\n",ans); return 0;}

 

转载于:https://www.cnblogs.com/JYYHH/p/8305048.html

你可能感兴趣的文章
Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)【转】
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>
IOS-图片操作集合
查看>>
IO—》Properties类&序列化流与反序列化流
查看>>
测试计划
查看>>
Mysql与Oracle 的对比
查看>>
jquery实现限制textarea输入字数
查看>>
Codeforces 719B Anatoly and Cockroaches
查看>>
jenkins常用插件汇总
查看>>
c# 泛型+反射
查看>>
第九章 前后查找
查看>>
Python学习资料
查看>>
jQuery 自定义函数
查看>>
jquery datagrid 后台获取datatable处理成正确的json字符串
查看>>
ActiveMQ与spring整合
查看>>
web服务器
查看>>
第一阶段冲刺06
查看>>
EOS生产区块:解析插件producer_plugin
查看>>