集训Day 1 2020.2.29 数论复习(gcd)(一)

集训 2020.2.29

数论复习--\(\gcd\)

gcd 的两种写法

\(\gcd(a,b)=\gcd(b,a\%b)=\gcd(a-b,b)\)

扩展gcd

找出一对整数\((x,y)\)使得\(ax+by=\gcd(a,b)\)
证明过程如下:

\(ax+by=\gcd(a,b)=d\),有\(b'x+(a\mod b)y'=d\)

\[bx'+\left(a-\left\lfloor\dfrac{a}{b}\right\rfloor b \right)y'=d \]

\[bx'+ay'-\left \lfloor \dfrac{a}{b} \right\rfloor by'=d \]

\[ay'+b\left(x'-\left\lfloor \dfrac{a}{b} \right\rfloor y' \right)=d \]

\[x=y',y=x'-\left\lfloor \dfrac{a}{b} \right \rfloor y' \]

变成了求\(bx'+(a\mod b)y'=d\)
然后再把这个式子递归下去,因为我们知道递归下去肯定会出现\(b=0\)的情况,此时我 们是可以求出\(x’\)\(y’\)的,之后再不断代回去,就能够求出一组解了。

不能理解也没关系,代码会背就好了!

背代码!

//1
void exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1;y=0;return;
	}
	exgcd(b,a%b,x,y);
	int temp;
	temp=x;
	x=y;
	y=temp-(a/b)*y;
	return ;
}
//2 紫书上的,更短更好背,也更容易让人迷糊
void exgcd2(int a,int b,int &x,int &y){
	if(!b){
		x=1;y=0;return ;
	}
	exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return ;
} 

求出通解

为了求出更多的解,我们有:

\[ax_1+by_1=ax_2+by_2=d \]

前两个式子移项得到:

\[a(x_1-x_2)=b(y_2-y_1) \]

这个式子除以\(d\)得到:

\[\dfrac{a}{d}(x_1-x_2)=a'(x_1-x_2)=\dfrac{b}{d}(y_1-y_2)=b'(y_2-y_1) \]

显然\(a',b'\)互质,因此\(x_1-x_2=kb',y_2-y_1=ka',k\in Z\)
因此我们得到了:\(x_2=x_1-kb',y_2=y_1+ka',k\in Z\)

求出\(x\)作为最小正整数的解

用公式:\(x=(x\%b+b)\mod b\)

更一般的问题

更一般地,求解\(ax+by=c\)的问题
裴蜀定理\(ax+by=c\)有解,当且仅当\(\gcd(a,b)|c\),即\(c=k\gcd(a,b),k\in Z\)
方程两边除以\(k\)得到:$$a\left( \dfrac{x}{k} \right)+b\left( \dfrac{y}{k} \right)=\gcd(a,b)$$
还元得到:\(ax_1+by_1=\gcd(a,b)\)
显然能够求出\(x_1,y_1\),因此也能求出原来的解

例题讲解

1 LGP1082 同余方程

求关于\(x\)的同余方程\(ax\equiv 1(\mod b)\)的最小正整数解。

题解

把这个同余式子转换一下就是\(ax\%b=1\),换句话说就是\(by+1=ax(y=\dfrac{a}{b})\)
移项之后得到\(ax+by=1\)(这样写的话\(y\)肯定就是负数了)
然后就用\(\operatorname{exgcd}\)即可。

2 LGP1516 青蛙的约会

纬线上有两只青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方 向,单位长度\(1\)米,这样我们就得到了一条 首尾相接的数轴。设青蛙A的出发点坐标是 \(x\),青蛙B的出发点坐标是\(y\)。青蛙A一次能跳\(m\)米,青蛙B一次能跳\(n\)米,两只青蛙跳 一次所花费的时间相同。纬度线总长\(L\)米。
现在要你求出它们跳了几次以后才会碰面。有可能永远碰不上。
其中\(0<x\neq y\le 2000000000,0<m,n<2000000000,0<L\le 210000000\)

题解

\(x_0\)为最终结果,让青蛙相对运动,可列出式子:\((m - n)x_0 =y-x(\mod L)\)
显然该式可以转化为:\((m - n)x_0 + Ly_0 = y - x\)
再变换一下变成:\(ax + by = c\)
变成了熟悉的\(\operatorname{exgcd}\)问题,正常求解即可。

3 CF527A Playing with Paper

一张纸长\(a\),宽\(b\)。每次我们切下来最大的正方形然后扔掉,直到剩下的纸也为正方 形即停。求剪出的正方形个数。

题解

本题答案是更相减损次数的个数,用辗转相除优化之
!!!

4 LGP5436 【XR-2】缘分

求不超过\(n\)的两个正整数的最小公倍数最大是多少.
\(n\le 10^9\)

题解

不难知道\(n\)\(n-1\)是互质的,显然没有比它俩还大的\(\operatorname{lcm}\)了,于是答案为\(n(n-1)\)
\(n=1\)不要忘了讨论了。还有\(\operatorname{long long}\)

5 LGP5535 【XR-3】小道消息

\(n\)个人,其中第\(i\)个人的衣服上有一个数\(i+1\),小X发现了一个规律:当一个衣服上的数为 \(i\) 的人在某一天知道了一条信息,他会在第二天把这条信息告诉衣服上的数为 \(j\)的人,其中$ \gcd(i,j)=1$(即 \(i,j\)的最大公约数为 \(1\))。在第 0 天,小 X 把一条小道消息告诉了第 \(k\) 个人,小 X想知道第几天时所有人都会知道这条小道消息。
可以证明,一定存在所有人都知道了这条小道消息的那一天。
提示:你可能需要用到的定理——伯特兰-切比雪夫定理。
\(2 \le n \le 10^{14}\)
\(1 \le k \le n\)

有关伯特兰—切比雪夫定理

伯特兰—切比雪夫定理说明:若整数\(n > 3\),则至少存在一个质数\(p\),符合\(n < p < 2n − 2\)
另一个稍弱说法是:对于所有大于\(1\)的整数\(n\),至少存在一个质数\(p\),符合\(n < p < 2n\)
其中两个加强结果(定理):
定理 1: 对任意自然数\(n > 6\), 至少存在一个\(4k + 1\)型和一个\(4k + 3\)型素数 \(p\) 使得\(n < p < 2n\)
定理 2: 对任意自然数\(k\), 存在自然数\(N\), 对任意自然数 \(n > N\)至少存在\(k\) 个素数\(p\)使得 \(n < p < 2n\)

题解

  1. 答案只可能是1或2
  2. \(k+1\)是质数的时候
    如果到\(n+1\)为止没有\(k+1\)的倍数时,显然答案为1
    如果有倍数的话,答案就是2,感性理解很显然,证明也不难,\(2(k+1)\)一定与\(2(k+1)-1\) 互质
  3. \(k+1\)不是质数的时候
    由那个奇怪的定理可知,一定存在一个质数\(p\)\(\dfrac{n}{2}\)\(n\)之间,显然\(k+1\)不可能是\(p\)的倍 数(\(2p>n\)),因此第一步先拿到p,然后 再由p传播到所有人

6 POJ2142:The Balanc

有一天平和两种数量无限的砝码(重为\(a\)\(b\)),天平左右都可以放砝码,称质量为\(c\) 的物品,要求:
放置的砝码数量尽量少;
当砝码数量相同时,总质量尽量小。

7 POJ2115:C Looooops

for(i=A;i!=B;i+=C){i%=1<< k;}
问:会循环多少次(有可能死循环)

8 JSK43512

https://nanti.jisuanke.com/t/43512

给出\(n\)个相邻酒桶在坐标轴的位置,要求通过移动一些酒桶,使得每个酒桶之间的距离为\(k\)
求最小移动距离
(另外这题评测机跑的飞快,你可以认为 1s 1e8)
\(1\le N,K\le 10^6\)

题解

我们设原始位置为 \(x\),第一个啤酒摊位置为\(a\),将其排序。某一油桶\(i\)位置是\(x_i\),它移动的距离是位置与它本来应该在的位置\(a+k(i-1)\)的差值,我们可以得到:

\[ans = \sum_{i=1}^n\vert x_i-[a+k(i-1)]\vert \]

通过移项,得到:

\[ans = \sum_{i=1}^n\vert [x_i-k(i-1)]-a \vert \]

通过预处理\(c_i=x_i-k(i-1)\),式子变形成为:

\[ans=\sum_{i=1}^n|c_i-a| \]

则转化到了:数轴上存在\(c_i\)的点,寻找一个点a使得ans最小,根据定理可知,a为c的中位数时ans有最小值。

定理:给定数轴上的\(n\)个点,求一个到他们的距离之和尽量小的点。
结论是:这个点是这\(n\)个数的中位数。所以只需排序即可。严谨的证明如下:
在数轴上标出这\(n\)个点,假定数轴上标好了六个点,从左到右编号\(C_i(i\in {1,2,3,4,5,6})\),如果选定\(C_4,C_5\)之间的一点\(\text P\),之后把这个点向左(或者向右,效果相同,假定向左)\(D\)个单位长度,则\(\text P′\)到它左边的四个点距离减少了\(4D\),到右边的两个点距离增加了\(2D\),总的来说距离减小了\(2D\)
通过这样的移动,发现在奇数个数构成的数列,满足条件的数是最中间的数,而偶数个数构成的数列是最中间两个数的平均数,得证。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int N=1e6+7;
ll n,k;
ll arr[N],c[N];

int main()
{
    scanf("%lld %lld",&n,&k);
    for(int i = 1;i <= n;i ++){
        scanf("%lld",&arr[i]);
    }
    sort(arr+1,arr+1+n);
    for(int i = 1;i <= n;i ++) c[i] = arr[i] - k*(i-1);
    sort(c+1,c+1+n);
    ll ans = c[(1+n)/2];
    if(n%2==0) ans = (c[n/2]+c[n/2+1])/2;
    ll sum = 0;
    for(int i = 1;i <= n;i ++){
        sum += abs(ans-c[i]);
    }
    printf("%lld",sum);
    return 0;
}
// by whh
posted @ 2020-02-29 21:40  刘子闻  阅读(337)  评论(0编辑  收藏  举报