1.1~n的全部数的最小公倍数:lightoj 1289  传送门

分析:素因子分解可知这个数等于小于1~n的全部素数的最高次幂的乘积

预处理1~n的全部质数,空间较大,筛选的时候用位图来压缩。和1~n全部

质数的乘积,剩下的就是找最高次幂的问题了。

代码例如以下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
using namespace std; const int maxn = 1e8+10; typedef unsigned int UI; UI tmp[5800000];
int vis[maxn/32+10];
int p[5800000],cnt; void init(){
cnt=0;
p[0]=tmp[0]=2;
cnt++;
IFOR(i,3,maxn-1,2){
if(!(vis[i/32]&(1<<(i%32)))){//用位图压缩节省空间
p[cnt]=i;
tmp[cnt]=tmp[cnt-1]*i;
cnt++;
IFOR(j,3*i,maxn-1,2*i) vis[j/32]|=(1<<(j%32));
}
}
} UI solve(int n){
int pos = upper_bound(p,p+cnt,n)-p-1;
UI ans = tmp[pos];
for(int i=0;i<cnt&&p[i]*p[i]<=n;i++){
int mul = p[i];
int ff=p[i]*p[i];
while(ff/mul==p[i]&&ff<=n){
mul=mul*p[i];
ff=ff*p[i];
}
ans=ans*(mul/p[i]);
}
return ans;
} int main()
{
init();
int t,cas=1,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("Case %d: %u\n",cas++,solve(n));
}
return 0;
}

2,1~n中最小公倍数等于n的数的对数 lightoj 1236传送门

非常明显这些数都是 n 的约数,

然后n=p1^a1*p1^a2*p3^a3...*pn^an;

对这两个数素因子分解要使得的每个素数ai的最高次等于ai,

因此对于每个因子的可能方案就有 (ai+1)*2-1;

代码例如以下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = 1e7+10; int p[maxn/5],tot;
bool vis[maxn];
void init(){
tot=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<maxn;i++){
if(!vis[i]){
p[tot++]=i;
for(int j=i+i;j<maxn;j+=i)
vis[j]=1;
}
}
} int main()
{
init();
int t,cas=1;
scanf("%d",&t);
while(t--){
long long n;
scanf("%lld",&n);
long long ans = 1;
for(int i=0;i<tot&&p[i]*p[i]<=n;i++){
if(n%p[i]==0){
long long cnt = 0;
while(n%p[i]==0)cnt++,n/=p[i];
ans=ans*(cnt*2+1);
}
}
if(n>1) ans*=3;
ans=ans/2+1;
printf("Case %d: %lld\n",cas++,ans);
}
return 0;
}

3. 1~n中随意两对数的最大公约数之和 UVA 11426

id=18553" target="_blank">传送门

我们设 f[n] = sigma(gcd(i , n)) 1<=i<n

那么 ans[n] = ans[n-1] + f[n];

在求f[n]的时候我们能够枚举gcd 然后f[n]+=gcd*phi(n/gcd);

代码例如以下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> #define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define maxn 4000001
#define LL long long
using namespace std; int phi[maxn]; LL ans[maxn];
LL f[maxn];
void init(){
FOR(i,1,maxn-1) phi[i]=i;
IFOR(i,2,maxn-1,2) phi[i]=phi[i]>>1;
IFOR(i,3,maxn-1,2){
if(phi[i]==i){
IFOR(j,i,maxn-1,i)
phi[j]=phi[j] -phi[j]/i;
}
}
} void solve(){
CLR(ans);
init();
FOR(i,1,maxn-1){
IFOR(j,i+i,maxn,i)
f[j]=f[j]+(LL)i*phi[j/i];
}
ans[1]=f[1];
FOR(i,2,maxn-1) ans[i]=ans[i-1]+f[i];
} int main()
{
solve();
int n;
while(~scanf("%d",&n)&&n){
printf("%lld\n",ans[n]);
}
return 0;
}

4.sigma(i,n) (1<=i<=n) 传送门

分析:

两个数的最小公倍数 = x*n/gcd(x,n);我们如果与n的最大公约数为g;

则与n的最大公约数的和g的最小公倍数的和为 n/g * (x1 + x2 + x3 + x(phi[n/g]))

小于等于n与n的最大公约数为g的数的个数为 Phi[n/h] 这里的phi表示的是欧拉函数

另一个结论就是 小于等于x与x互质的数的和 = phi[x]*x/2;

证明:

if gcd(n,i)=1 then gcd(n,n-i)=1 (1<=i<=n)

反证法:

         假设存在K!=1使gcd(n,n-i)=k,那么(n-i)%k==0

         而n%k=0

         那么必须保证i%k=0

         k是n的因子,假设i%k=0那么 gcd(n,i)=k,矛盾出现;

         于是问题变的很easy: ANS=N*phi(N)/2

         i,n-i总是成对出现,而且和是n

        于是可能就有人问了,假设存在n-i=i那不是反复计算?

         答案是不会

         由于:

                 n=2*i->i=n/2

         1.假设n是奇数,那么n!=2*i,自然也不存在 n-i=i和反复计算之说

         2.假设n是偶数,n=2*i成立,gcd(n,n/2)必定为n的一个因子,这个因子为1当且仅当n==2

         于是对于n>2的偶数。绝对不存在gcd(n,n/2)=1所以更别说什么反复计算了

         对于n==2

         ans=2*1/2=1,正好也满足

         所以得到终于公式:

                  ans=N*phi(N)/2

因此这道题目的终于公式就是 n*sigma(phi[n/x]*n/x/2) x|n;

代码例如以下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> #define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define maxn 1000001
#define LL long long
using namespace std; //const LL mod = 1e9+7; int phi[maxn];
void init(){
FOR(i,1,maxn-1) phi[i]=i;
IFOR(i,2,maxn-1,2) phi[i]=phi[i]>>1;
IFOR(i,3,maxn-1,2){
if(phi[i]==i){
IFOR(j,i,maxn-1,i)
phi[j]=phi[j] -phi[j]/i;
}
}
} LL ans[maxn];
void solve()
{
init();
int i,j;
FOR(i,1,maxn-1){
IFOR(j,i,maxn-1,i)
ans[j]=ans[j]+(LL)phi[j/i]*(LL)j/i/2;
}
} int main()
{
solve();
int n,t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("%lld\n",(ans[n]+1)*n);
}
return 0;
}

GCD&amp;&amp;LCM的一些经典问题的更多相关文章

  1. 最大公约数(GCD)与最小公倍数(LCM)的计算

    给出两个数a.b,求最大公约数(GCD)与最小公倍数(LCM) 一.最大公约数(GCD)    最大公约数的递归:  * 1.若a可以整除b,则最大公约数是b  * 2.如果1不成立,最大公约数便是b ...

  2. ACM数论之旅3---最大公约数gcd和最小公倍数lcm(苦海无边,回头是岸( ̄∀ ̄))

    gcd(a, b),就是求a和b的最大公约数 lcm(a, b),就是求a和b的最小公倍数 然后有个公式 a*b = gcd * lcm     ( gcd就是gcd(a, b), ( •̀∀•́ ) ...

  3. Solve Equation gcd(x,y)=gcd(x+y,lcm(x,y)) gcd(x,y)=1 => gcd(x*y,x+y)=1

    /** 题目:Solve Equation 链接:http://acm.hnust.edu.cn/JudgeOnline/problem.php?id=1643 //最终来源neu oj 2014新生 ...

  4. hdu 5974 A Simple Math Problem gcd(x,y)=gcd((x+y),lcm(x,y))

    题目链接 题意 现有\[x+y=a\\lcm(x,y)=b\]找出满足条件的正整数\(x,y\). \(a\leq 2e5,b\leq 1e9,数据组数12W\). 思路 结论 \(gcd(x,y)= ...

  5. 最大公约数gcd与最小公倍数lcm

    最大公约数:gcd 最大公倍数:lcm gcd和lcm的性质:(我觉得主要是第三点性质) 若gcd (

  6. 最大公约数gcd、最小公倍数lcm

    最大公约数(辗转相除法) 循环: int gcd(int a,int b) { int r; ) { r=b%a; b=a; a=r; } return b; } 递归: int gcd(int a, ...

  7. Mathematics:GCD & LCM Inverse(POJ 2429)

    根据最大公约数和最小公倍数求原来的两个数 题目大意,不翻译了,就是上面链接的意思. 具体思路就是要根据数论来,设a和b的GCD(最大公约数)和LCM(最小公倍数),则a/GCD*b/GCD=LCM/G ...

  8. POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)

    题意:给出a和b的gcd和lcm,让你求a和b.按升序输出a和b.若有多组满足条件的a和b,那么输出a+b最小的.思路:lcm=a*b/gcd   lcm/gcd=a/gcd*b/gcd 可知a/gc ...

  9. [POJ 2429] GCD & LCM Inverse

    GCD & LCM Inverse Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10621   Accepted: ...

随机推荐

  1. [Spring] Spring Boot 生态

  2. selenium3+python-多窗口、句柄(handle)

    一.获取当前窗口句柄 1.元素有属性,浏览器的窗口其实也有属性的,只是你看不到,浏览器窗口的属性用句柄(handle)来识别. 2.人为操作的话,可以通过眼睛看,识别不同的窗口点击切换.但是脚本没长眼 ...

  3. android 可拖动控件 ontouchevent

    首先附上文章的转载内容的链接: 学习android 可拖动事件首先需要对android的屏幕和touchevent参数建立一个详细的知识结构. 1.android坐标系统 一.首先明确一下 andro ...

  4. POJ 3253 STL优先队列

    题目大意:FJ需要修补牧场的围栏,他需要 N 块长度为 Li 的木头(N planks of woods).开始时,FJ只有一块无限长的木板,因此他需要把无限长的木板锯成 N 块长度 为 Li 的木板 ...

  5. 全局设置border-box

    全局设置 border-box 很好,更符合我们通常对一个「盒子」尺寸的认知.,其次它可以省去一次又一次的加加减减,它还有一个关键作用——让有边框的盒子正常使用百分比宽度.但是使用了 border-b ...

  6. 五分钟学习React(六):元素(Element)和组件(Component)

    俗话说"万丈高楼平地起",从这一期开始,我们将使用基于Webpack+Babel的React学习React框架中的一些基础概念.在学习React的过程中经常会把Element.Cl ...

  7. Android 在线升级

    1.获取当前安装版本 //获取当前版本 public int getVersion(Context context){ ; try { version = context.getPackageMana ...

  8. Matlab数组创建

    只用C语言,不用Matlab这种魔咒还是要打破的.Matlab是科学计算的常用工具,既然以前没用过,现在开始学吧...... 1.   向量的创建 1)直接输入: 行向量:a=[1,2,3,4,5] ...

  9. C# for 遍历 IPagedList

    IPagedList<Doc> ss = Doclist.ToPagedList(page, pageSize); ;i<ss.Count;i++) { var yy = ss[i] ...

  10. eas之事件

    选择事件 选择事件是在选择块发生变化后发出.table.addKDTSelectListener(new KDTSelectListener(){    public void tableSelect ...