51nod 1575 Gcd and Lcm
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1575
万年巨坑终于填掉了……
首先是煞笔西瓜的做题历程O_O。
原题要求$\sum_{i=1}^n\sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)]$
那么先推一波式子吧
balabala
我也忘记自己是怎么推的了(雾
总之最后推出来是这样的
$ ans=\sum_{i=1}^{n} f(\left\lfloor\frac{n}{i}\right\rfloor)*g(i) $
其中 $ f(x)=\sum_{i=1}^{x} μ(i)*i^2*\frac{\frac{x}{i}(\frac{x}{i}+1)}{2} $ ,$ g(x)=[\sum_{d|x} \frac{x}{d}*φ(d)]^2 $
然后接下来的问题就是怎么求f(x)的值和g(x)的前缀和了,求出来就能分段计算辣。
嗯……
想想怎么求……
$ μ(i)*i^2 $ 可以用杜教筛直接求嘛,然后f(x)就可以O(3/4)分段求,可是在总式里面再跑一次分段的话复杂度会……诶,不管了,先写。
g(x)的前缀和可以洲阁筛求,嗯,码码码……(这么复杂的题怎么才7级?
啊,T了,意料之中……
改改改
跑得越来越快了……
诶,极限数据要跑两秒多,可是10组数据的话还是要10多秒
改不动,弃坑……
(51nod群上问了下,夹克老爷说他不会。
问问YJQ
他说$ \sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)] $ 这东西是个积性函数。
所以直接用洲阁筛对这个东西求前缀和就好了(掀桌……
也就是说,看到题目,你开始推式子,你就输辣。
具体来说,对于一个质数$ p $,当 $ i=p^k $ 时,$ \sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)] =(2k+1)*(p^{2k}-p^{2k-1})+p^{k-1} $
优越写法才2.8k,第一种方法直接上5k……
代码不贴辣。
upd at 2017.4.26好像这题烂大街了,我来发个洲阁筛模板吧
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ui unsigned int
#define ull unsigned long long
#define MN 100001
#define SQ 64000
using namespace std;
ui read_p,read_ca;
inline ui read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
const ui HA=1e6+;
ui T,n,MMH,p[MN/],_p[MN/],num=,TTT,O,Num,f[SQ],_S[SQ],G_2[SQ],G_1[SQ],G_0[SQ],_T[SQ],P_P[MN/],_G_2[MN/],_G_1[MN/],_O[SQ],_Num,_l[HA],NNN=,LL;bool bo[MN];
ui gcd(ui x,ui y){return y?gcd(y,x%y):x;}
ui _b_y[HA],_b_z[HA],_b_ne[HA];
inline void _in(ui x,ui y,ui z){_b_y[++_Num]=y;_b_z[_Num]=z;_b_ne[_Num]=_l[x];_l[x]=_Num;}
inline ui Q_2(ui x){if (x%==)return (ull)(x+x+)*(x+)/*x;else if (x%==) return (ull)(x+x+)*x/*(x+);else return (ull)x*(x+)/*(x+x+);}
inline ui Q_1(ui x){return (ull)x*(x+)>>;}
inline ui sqr(ui x){return x*x;}
inline ui min(ui a,ui b){return a<b?a:b;}
inline ui find(ui x){
if (x<HA) return _b_z[_l[x]];
register ui i;
for (i=_l[x%HA];i;i=_b_ne[i]) if (_b_y[i]==x) return _b_z[i];
return ;
}
inline ui Mmh(ui n){
register ui i,j,c;ui o=sqrt(n)+1e-,MMH=,k=,R,Ls,Rs,P,SS=;ull x,Q,O_O;
while (p[LL+]<=o&&LL<num) LL++;
for (i=;i<=n;i=j+) j=n/(c=n/i),_S[++k]=c,_in(c%HA,c,k),_T[k]=f[k]=,G_2[k]=Q_2(c),G_1[k]=Q_1(c),G_0[k]=c;
for (i=k,j=;i;_O[i--]=j) while (_S[i]>=p[j+]) j++;
for (f[i=]=,P=Ls=Rs=k;i<=LL;i++){
if (i==) while (_S[P]<_p[i]&&P) P--;else P=Rs;
while (_S[Rs]<_p[i+]&&Rs) SS+=f[Rs--];
while (_S[Ls]<p[i+]&&Ls) SS-=f[Ls--];
if (i!=LL) MMH+=SS*P_P[i+];
for (j=P;j;j--)
if (f[j]){
for (x=p[i],Q=,c=;x<=_S[j];x*=p[i],Q*=p[i],c++){
R=find(_S[j]/x);
f[R]+=(O_O=f[j]*((*c+)*(p[i]-)*sqr(Q)*p[i]+Q));if (Ls>=R&&R>Rs) SS+=O_O;
if (i!=LL) if (_S[R]>=p[i+]&&_S[R]<_p[i+]) MMH+=O_O*P_P[i+];
}
}
for (j=;j<=P;j++)
if (_S[j]>=p[i]) c=min(i-,_O[R=find(_S[j]/p[i])]),
G_2[j]-=_p[i]*(G_2[R]-(_G_2[c]-_G_2[_T[R]]))+(_G_2[i-]-_G_2[_T[j]]),
G_1[j]-=p[i]*(G_1[R]-(_G_1[c]-_G_1[_T[R]]))+(_G_1[i-]-_G_1[_T[j]]),
G_0[j]-=(G_0[R]-(c-_T[R]))+(i--_T[j]),_T[j]=i;
}
for (j=;j<=k;j++) c=min(LL,_O[j]),G_2[j]-=_G_2[c]-_G_2[_T[j]],G_1[j]-=_G_1[c]-_G_1[_T[j]],G_0[j]-=c-_T[j];
for (i=;i<=k;i++) MMH+=f[i]*((G_2[i]-G_1[i])*+G_0[i]),_l[_S[k]%HA]=;
return _Num=,MMH;
}
int main(){
register ui i,j;
for (i=;i<MN;i++){
if (!bo[i]) p[++num]=i,_p[num]=p[num]*p[num],_G_2[num]=_G_2[num-]+_p[num],_G_1[num]=_G_1[num-]+p[num],P_P[num]=*p[num]*(p[num]-)+;
for (j=;j<=num&&(O=i*p[j])<MN;j++){
bo[O]=;
if (!i%p[j]) break;
}
}
T=read();while(T--){
n=read();
printf("%u\n",Mmh(n));
}
}
51nod 1575 Gcd and Lcm的更多相关文章
- 51Nod 2026 Gcd and Lcm
题目传送门 分析: 开始玩一个小小的trick 我们发现\(f(n)=\sum_{d|n}\mu(d)\cdot d\)是一个积性函数 所以: \(~~~~f(n)=\prod f(p_i^{a_i} ...
- HDOJ 4497 GCD and LCM
组合数学 GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- hdu 4497 GCD and LCM 数学
GCD and LCM Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4 ...
- GCD 与 LCM UVA - 11388
题目链接: https://cn.vjudge.net/problem/23709/origin 本题其实有坑 数据大小太大, 2的32次方,故而一定是取巧的算法,暴力不可能过的 思路是最大公因数的倍 ...
- 简单数论总结1——gcd与lcm
并不重要的前言 最近学习了一些数论知识,但是自己都不懂自己到底学了些什么qwq,在这里把知识一并总结起来. 也不是很难的gcd和lcm 显而易见的结论: 为什么呢? 根据唯一分解定理: a和b都可被分 ...
- poj 2429 GCD & LCM Inverse 【java】+【数学】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9928 Accepted: ...
- HDU 4497 GCD and LCM (合数分解)
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
- hdu4497 GCD and LCM
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- HDU 4497 GCD and LCM(数论+容斥原理)
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
随机推荐
- iOS Swift3.0 OC 数据储存--归档
一.Swift 3.0 1.model class userModel: NSObject,NSCoding { var account: String = "" var regm ...
- iOS动态性:动态添加属性的方法——关联(e.g. 向Category添加属性)
想到要如何为所有的对象增加实例变量吗?我们知道,使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量.不过从Mac OS X v10.6开始,系统提供了Associative ...
- iOS 获取当前应用的信息以及用户信息:版本号手机号手机型号
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; CFShow(infoDictionary); // ap ...
- Kendo UI使用笔记
1.Grid中的列字段绑定模板字段方法参数传值字符串加双引号: 上图就是个典型的例子,openSendWin方法里Id,EmergencyTitle,EmergencyDetail 三个参数,后两个参 ...
- bzoj 3675: [Apio2014]序列分割
Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...
- 7.18 DP考试解题报告
今天的考试真的是天崩地裂,写了的三个题全炸...然而谁叫我弱+不注意细节呢???真的要扇耳光... T1:题意:一段区间的高度为这个区间中高度的最小值,给定n个宽度,求每个宽度的期望高度 40% :算 ...
- Python的文件及异常
1. Python的文件及异常 1.1 文件操作 1.1.1 从文件中读取数据 许多情况下,我们的信息是存储在文本中的.例如对用户行为的分析,用户访问系统或者网站的访问信息会被存储于文本中,然后对文本 ...
- php实现MySQL读写分离
MySQL读写分离有好几种方式 MySQL中间件 MySQL驱动层 代码控制 关于 中间件 和 驱动层的方式这里不做深究 暂且简单介绍下 如何通过PHP代码来控制MySQL读写分离 我们都知道 &q ...
- Linux小记
一.在vim中如何查看正在编辑的文件名 在正常模式下: :f 或 CTRL+G 查看文件的路径 用:!pwd 可以看当前的详细路径. 二.crontab 在crontab中, 命令crontab -e ...
- perl多线程使用
原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun <<=========================threa ...