没想到NOI竟然还有这种数学题,看来要好好学数论了……

网上的题解:

完整的结题报告:

首先我们需要知道一个知识,对于坐标系第一象限任意的整点(即横纵坐标均为整数的点)p(n,m),其与原点o(0,0)的连线上除过原点整点的个数为gcd(n,m)。其他象限上个数则为gcd(abs(n),abs(m)),这里的gcd(a,b)是指a与b的最大公约数(Greastest Common Divisor),abs(a)是指数a的绝对值。
证明:
考虑在op上最小的一个整点(x,y),这里的最小是指横纵坐标绝对值最小,x与y必然满足gcd(x,y)=1,即x与y互质。因为若不互质的话,将x与y均除去他们的公约数后可以产生一个更小的整点。则显然有(kx,ky){x<=kx<=n,k属于正整数}也在线段op上,而且这些点也是op上全部的整点,显然这些点的个数等于最大的那个k。为方便叙述我们直接将其称为k,其满足kx=n,ky=m。则显然k=gcd(n,m),证明完毕。
则现在我们只需要求出每一个gcd(n,m)即可,这里我们可以使用经典的欧几里德算法,其的复杂度为O(lgb),b为两个数中较小的那个。总的复杂度将为O(n^2lgn)但是考虑到此题的规模极大,此方法必然超时。
进一步考虑,我们不难发现要求的最大公约数的规模相对于所有数对的规模要小的多。所以我们可以转而求对于一个数p(p<min(n,m)),满足gcd(a,b)=p的数对(a,b)的个数。
令num[i]表示最大公约数为i的数对的个数,bound为min(n,m)。首先可以知道公约数有i的数对的个数应为(n div i)*(m div i),这个是比较好想的,然而并没有满足要求,因为i并不为最大公约数。不过处理方法很简单,考虑到这些当前的数对可能存在比i更大的公约数为2i,3i,4i...ki(ki<=bound),只需将这些数对删去即可。
这样我们就有了整体框架,首先可以直接求出num[bound] = (n div bound)*(m div bound),按照从大到小的顺序求num[i]即可,num[i] = (n div i)*(m div i)-Sigma(num[ki]) , 1<=ki<=bound) (那个求和的符号我打不出来...)
则代价的总和为2*Sigma(num[i]*i)-nm(因为题目中要求的线段上的整点不包括端点,而我们算的gcd(a,b),其中包括了点(a,b))。

我的代码:

 var n,m,ans,d:int64;
g:longint;
f:array[..] of int64;
function min(x,y:int64):int64;
begin
if x<y then min:=x else min:=y;
end;
begin
ans:=;
readln(n,m);
for g:=min(n,m) downto do
begin
f[g]:=(n div g)*(m div g);
d:=g+g;
while d<=min(n,m) do
begin
dec(f[g],f[d]);
inc(d,g);
end;
end;
for g:=min(n,m) downto do
inc(ans,f[g]*(*g-));
writeln(ans);
end.

ps:f[i]:=(n div i )* (m div i)

在这个式子中,即使 f 数组为 int64 数组,但n,m为 longint ,当n=m=100000时还是会发生溢出,所以n,m也必为 inf64

这种容易忽视的错误需要注意,即参与四则运算的变量必须能承载运算结果!

UPD:更简单的莫比乌斯反演

sigma(gcd(x,y))1<=x<=n,1<=y<=m=sigma(fai[k]*(n/k)*(m/k)) 1<=k<=min(n,m)

线性筛就行了。

代码:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 100000+5
#define maxm 100000+5
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
ll n,m,p[maxn],tot,fai[maxn];
ll ans;
bool v[maxn];
inline void get()
{
fai[]=;
for2(i,,m)
{
if(!v[i])p[++tot]=i,fai[i]=i-;
for1(j,tot)
{
int k=p[j]*i;
if(k>m)break;
v[k]=;
if(i%p[j])fai[k]=fai[i]*(p[j]-);
else {fai[k]=fai[i]*p[j];break;}
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();m=read();
if(n<m)swap(n,m);
get();
for1(i,m)ans+=fai[i]*(n/i)*(m/i);
cout<<n*m+*(ans-n*m)<<endl;
return ;
}

NOI2010能量采集(数论)的更多相关文章

  1. BZOJ 2005: [Noi2010]能量采集( 数论 + 容斥原理 )

    一个点(x, y)的能量损失为 (gcd(x, y) - 1) * 2 + 1 = gcd(x, y) *  2 - 1. 设g(i)为 gcd(x, y) = i ( 1 <= x <= ...

  2. Luogu P1447 [NOI2010]能量采集 数论??欧拉

    刚学的欧拉反演(在最后)就用上了,挺好$qwq$ 题意:求$\sum_{i=1}^{N}\sum_{j=1}^{M}(2*gcd(i,j)-1)$ 原式 $=2*\sum_{i=1}^{N}\sum_ ...

  3. [BZOJ2005][Noi2010]能量采集 容斥+数论

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 4394  Solved: 2624[Submit][Statu ...

  4. BZOJ 2015:[Noi2010]能量采集(数论+容斥原理)

    2005: [Noi2010]能量采集 Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物 ...

  5. BZOJ 2005 [Noi2010]能量采集 (数学+容斥 或 莫比乌斯反演)

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 4493  Solved: 2695[Submit][Statu ...

  6. luogu1447 [NOI2010]能量采集 莫比乌斯反演

    link 冬令营考炸了,我这个菜鸡只好颓废数学题了 NOI2010能量采集 由题意可以写出式子: \(\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\) \(=2\sum ...

  7. BZOJ 2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 3312  Solved: 1971[Submit][Statu ...

  8. noi2010 能量采集

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MB Submit: 3068  Solved: 1820 [Submit][Sta ...

  9. bzoj2005: [Noi2010]能量采集

    lsj师兄的题解 一个点(x, y)的能量损失为 (gcd(x, y) - 1) * 2 + 1 = gcd(x, y) *  2 - 1. 设g(i)为 gcd(x, y) = i ( 1 < ...

  10. 2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 1831  Solved: 1086[Submit][Statu ...

随机推荐

  1. Linux Mint SmoothTask2的安装方法

    首先,先下载smooth task:点击这里下载 下载之后解压缩,里面有个install文件,点击打开: To install plasmoid unpack archive, go to the d ...

  2. NOSQL Mongo入门学习笔记 - MongoDB的安装(一)

    手上的工作不是很忙,所以来学习学习很久就像接触的MongoDb,无奈前段时间工作时间都比较多.记录在这里供以后参考 环境: Centos 7 64位 开始: 1. 在官网下载Mongo : wget  ...

  3. Android EditText边框颜色的selector 使用focus标记当前填写的框

    案例:当选中一个EditText时,将其边框变为蓝色,其他未被选中的EditText则为灰色. 主界面: <?xml version="1.0" encoding=" ...

  4. android 从系统相册获取一张图片

    package net.viralpatel.android.imagegalleray; import android.app.Activity; import android.content.In ...

  5. UIcollectionView的使用(首页的搭建1)

    今天做一个首页的效果:  首页是用UICollectionView做的.下面我来结合首页的效果介绍一下: 一.创建基类继承自UIViewController 01 创建基类继承自UIViewContr ...

  6. spring IOC容器实例化Bean的方式与RequestContextListener应用

    spring IOC容器实例化Bean的方式有: singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时, ...

  7. 解决浮层弹出如何加上datepicker,并且浮动在上面

    最近在做一个弹出层上弹出的对话框中能弹出一个截止时间的选择框,这个选择框使用datepicker来做. 效果大致是这样的: 但是在做的时候,遇到一个问题,datepicker在弹出层的时候,时间选择框 ...

  8. 命令行添加用户的“作为服务登录”权利(添加Windows用户的时候,门道不是一般的多)good

    1.打开控制台(“开始”|“运行”中输入:MMC) 2.“文件”菜单|“添加删除管理单元”|“添加...”|选“安全模板”|“关闭”. 3.在“C:\Windows\Security\template ...

  9. Android:android:gravity 和 android:layout_Gravity 的区别

    LinearLayout有两个非常相似的属性:android:gravity与android:layout_gravity. android:gravity 属性是对该view中内容的限定 andro ...

  10. 172. Factorial Trailing Zeroes

    题目: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...