[关闭]
@poorpool 2017-10-05T20:07:21.000000Z 字数 4199 阅读 1148

清北学堂金秋营 day5

%%%zrt

题解


T1

先排个序。
能拼出[0,x],现在最小的是k。要是k>x+1,岂不是x+1拼不出来。
考虑前缀和+1与下一个元素的关系。

T2

(默默地打表找规律23333)
答案的数量级是级别的。

30:直接枚举。
60:

  1. for(int i=1; i<=n; i++){
  2. int a=n/i;
  3. int b=n/a;
  4. i = b;
  5. //a偏小,则b偏大。
  6. //blablabla
  7. }

100:
分成几部分来看。
第一部分是除以不同的i得到不同的解;
第二部分是除以不同的i的得到有重复的解,且他们连续。
二分第一个满足n/i-n/(i+1)<=1(实数除)

T3

直接搜是2^30复杂度太高。
分两半搜,变成2*2^15。
搜出2^15个三元组。
按照钻石数、钱数排序而分类。
又搜出另一半的2^15个三元组。
后来的三元组,每个三元组都对前面的三元组有一个严格要求(钻石数)。因此,后面的每个三元组,与前面三元组结合必定为一个区间(因为你排的序)。可用前缀和预处理前面的三元组。

数论


快速幂

  1. int ksm(int a,int b,int p){
  2. if(!b)return 1%p;
  3. int c=pow(a,b/2,p);
  4. c=c*c%p;
  5. if(b%1)c=c*a%p;
  6. return c;
  7. }
  8. //or
  9. int ksm(int a, int b, int c){
  10. int ret=1%p;
  11. while(b){
  12. if(b&1)ret=ret*a%p;
  13. b>>=1;
  14. a=a*a%p;
  15. }
  16. return ret;
  17. //2^n=2^(2^0+2^1+2^2...(二进制分解))
  18. }

noip 转圈游戏

素数

判断素数。
学miller-rabin

唯一分解定理

1

筛素数

O(nlogn)埃拉托斯特尼筛
O(n)线性筛(欧拉筛)

  1. for(int i=2; i<=n; i++){
  2. if(!mindiv[i]/*最小素因子*/){
  3. mindiv[i] = i;
  4. prime[++tot] = i;
  5. }
  6. for(int j=1; prime[j]*i<=n; j++){
  7. mindiv[prime[j]*i] = prime[j];
  8. if(prime[j]!=mindiv[i]) break;
  9. }
  10. }
  11. //or
  12. for(int i=2;i<=listsize;i++){
  13. if(isprime[i])prime[++primesize]=i;
  14. for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++){
  15. isprime[i*prime[j]]=false;
  16. if(i%prime[j]==0)break;
  17. }
  18. }

gcd and lcm

(a, b)==gcd(a, b)
辗转相减:(a, b)=(a, a-b)(a>b)

x|a,x|b ---> x|(ap+bq)

进化即辗转相除:

  1. int gcd(int a, int b){
  2. return !b?a:gcd(b, a%b);
  3. }

复杂度log级

lcm(a, b) = a/gcd(a, b)*b
事实上
a=p1^a1 * p2^a2 * ...
b=p1^b1 * p2^b2 * ...
(a, b) = p1^min(a1, b1) * p2^min(a2, b2) * ...
[a, b] = p1^max(a1, b1) * p2^max(a2, b2) * ...

费马小定理

if p is a prime,then

证明

一、准备知识:
引理1.剩余系定理2
若a,b,c为任意3个整数,m为正整数,且(m,c)=1,则当ac≡bc(modm)时,有a≡b(modm)
证明:ac≡bc(mod m)可得ac–bc≡0(mod m)可得(a-b)c≡0(mod m)因为(m,c)=1即m,c互质,c可以约去,a–b≡0(mod m)可得a≡b(mod m)
引理2.剩余系定理5
若m为整数且m>1,a1,a2,a[3],a[4],…a[m]为m个整数,若在这m个数中任取2个整数对m不同余,则这m个整数对m构成完全剩余系.
证明:构造m的完全剩余系(0,1,2,…m-1),所有的整数必然这些整数中的1个对模m同余.取r1=0,r2=1,r[3]=2,r[4]=3,…r=i-1,1
引理3.剩余系定理7
设m是一个整数,且m>1,b是一个整数且(m,b)=1.如果a1,a2,a3,a4,…am是模m的一个完全剩余系,则ba1,ba2,ba[3],ba[4],…ba[m]也构成模m的一个完全剩余系.
证明:若存在2个整数ba[i]和ba[j]同余即ba[i]≡ba[j](mod m),根据引理2则有a[i]≡a[j](mod m).根据完全剩余系的定义和引理4(完全剩余系中任意2个数之间不同余,易证明)可知这是不可能的,因此不存在2个整数ba和ba[j]同余.由引理5可知ba1,ba2,ba[3],ba[4],…ba[m]构成模m的一个完全剩余系.
引理4.同余定理6
如果a,b,c,d是四个整数,且a≡b(mod m),c≡d(mod m),则有ac≡bd(mod m)
证明:由题设得ac≡bc(mod m),bc≡bd(mod m),由模运算的传递性可得ac≡bc(mod m)
二、证明过程:
构造素数p的完全剩余系P={1,2,3,4…(p-1)},因为(a,p)=1,由引理3可得A={a,2a,3a,4a,…(p-1)a}也是p的一个完全剩余系.令W=1*2*3*4…*(p-1),显然W≡W(mod p).令Y=a*2a*3a*4a*…(p-1)a,因为{a,2a,3a,4a,…(p-1)a}是p的完全剩余系,由引理2以及引理4可得a*2a*3a*…(p-1)a≡1*2*3*…(p-1)(mod p)即W*a^(p-1)≡W(modp).易知(W,p)=1,由引理1可知a^(p-1)≡1(modp)

逆元

3
先处理n!逆元。

裴蜀定理

if a,b is int,(a,b)=d,对任意x,y as int,ax+by为d倍数。特别的,一定存在x,y使得ax+by=d成立

扩展欧几里得

初始时有x=1,y=0
每次把b,a%b的xy变成a,b的xy
x*b+y*(a%b)=(b,a%b)=xb+y(a-*b)=ya+(x-*y)b
x'a+y'b=gcd(a,b)
即x'=y,y'=x-a/b

  1. int ExGCD(int a, int b, int& x, int& y)
  2. {
  3. if(b == 0)
  4. {
  5. x = 1, y = 0;
  6. return a;
  7. }
  8. int d = ExGCD(b, a%b, x, y);
  9. int temp = x;
  10. x = y;
  11. y = temp - a/b*y;
  12. return d;
  13. }

noip2012 同余方程

求ax=1(mod b)
保证有解

即ax+by=1
因为保证有解,所以(a, b)|1(证明:要是gcd!=1,那左边就是整数乘整数必!=1)

ax+by=1,则a(x+b)+b(y-a)=1
(加了一个ab减了一个ab)

解同余思想

欲求ax+by=c
先求ax+by=(a, b)=gcd
同乘c/gcd,得出
ax+by=c的一组解,再得出
a(x+b/gcd)+b(y-a/gcd)=c
(为什么是b/gcd,a/gcd呢?这样可以最大程度把区间长度比解数缩小,从而做到“最小整数解”)

中国剩余定理(CRT)

解同余方程组

有:
x % p1 = a1
x % p2 = a2
x % p3 = a3
...
x % pn = an
各p互素

令m=p1p2p3...pn
构造出
//ni(k,p)是k在模p意义下逆元
x = (m/p1*ni(m/p1, p1)*a1 + ...) c% m

x + k1*p1 = a1
x + k2*p2 = a2
联立(上下相减)
k1p1-k2p2 = a1-a2

欧拉定理

剩余系

模一个数字得到的结果即为一个剩余系。
{1,2,...p-1}(不考虑0)
12:{1,2,3...12}

简化剩余系

只拿出和p 互素
12:{1,5,7,11}

定理

如果(a, m)=1,a^phi(m)=1(mod m)

如果(a,b)=1

如果p为素数

pick定理

格点多边形公式:
S=a+b/2-1
其中a表示多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积。
poj2954

如果两格点横距a纵距b,则再走a/x,b/x(x|a,x|b)到下一格点,即欲使最优,则x=(a, b)

矩阵乘法

在这里我们谈方的。

  1. int a[][]
  2. int b[][]
  3. int c[][]
  4. for(int i=1; i<=n; i++)
  5. for(int j=1; j<=n; j++)
  6. for(int k=1; k<=n; k++)
  7. c[i][j]+=a[i][k]*b[k][j];

f[1~n]
if f[i]*k -> f`[j]
then a[i][j] = k

有结合律无交换律。

考虑斐波那契数列,fib[i]=fib[i-1]+fib[i-2]
f1=fib[k] f2=fib[k+1]
f'1=fib[k+1] f`2=fib[k+2]
(笔者是沙茶啥也不会)

分治乘法

?????

组合数学


推荐《组合数学》



c[n][m]=c[n-1][m]+c[n-1][m-1]

lucas定理

c[n][m]%p=c[n%p][m%p]*c[n/p][m/p]%p

一些题目


poj1006 biorhythms

x % [p1, p2]=
(k - x) % 23 = 0
(k - y) % 28 = 0;

余数之和

求x%1+x%2+x%3+...+x%n
范围10^12

即x-x/1*1+x-x/2*2+x-x/3*3+...+x-x/n*n=nx-...-(x/i * i+x/(i+1) * i+1+x/(i+2) * (i+2)-...= nx-...-(x/i)(i+i+1+i+2...)-...
(这啥???)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注