數學

aka 高中數學 in 資訊

這份簡報會跟去年的長很像

但是我多放了很多 AGC

所以刷不動不用洩氣,我也刷不動

簡介

競賽數學主要分 ACGN 四大類

Algebra 代數

Combinatory 組合

Geometry 幾何

Number theory 數論

不是 Animation, Comic, Game, Novel 啦

資訊用到的數學

\(C \approx N > A > G\)

然後要會一點向量、線性代數、群論

如果你去年聽過了

來做怪題

題目是真的挺怪的,但是非常好數學,數學非常好

第三題是純幾XD

構造題

八維立方體 CF 1543 E

蠻酷的想法

AGC 027 D

第一步也是最通靈的一步:假設黑白染色,滿足每對相鄰的點的黑點都 > 白點

可以發現黑點就是 lcm of 相鄰的白點

又要 <= 10^15,10^15^(1/4) = 10^(3.75) ~= 5600

考慮一個格子,他是剛好兩條對角線的交點

假設每條對角線代表一個質數,白格是兩條對角線的乘積

因此白格互不相同

那麼黑格就是所有相鄰的點的對角線代表的值的乘積,由於只有 1000 條對角線,所以只要對角線的值不要太大就好

算一下第 1000 個質數是 7919,好好配一下(例如大小相間)就可以了

跟上一題有點像

AGC 030 C

首先 k <= 500 那就大小是 k 然後第 i 行塗第 i 種顏色,完美

下面考慮 k > 500 的時候

前面的東西我想了很久還是不知道怎麼改

沒關係,我說的是跟上一題有點像

對角線有用嗎

都說了就是有用

觀察到 500%2 == 0

考慮 k = 500,n = 500 且第 i 條主對角線塗顏色 i

那可以發現 i 只跟 i+1 還有 i-1 相鄰

這提供了我們一個改法

第 i 條對角線改塗 i 與 i+500,如果 i+500 <= k 的話

done!

跟上一題有點像

AGC 030 C

純走路

AGC 041 C

AGC 035 C

我居然沒講二進位分解

AGC 012 C

構造操作題

AGC 063 C

AGC 047 E

 

是說我很想出操作題但是我出不出來

數論

同餘

a 與 b 在模 p 下同餘若且唯若 (a-b)%p == 0

這裡的 p 不一定是質數

加法、減法、乘法

const int mod=998244353;
void add(int& x,int y){
    x+=y;
    x-=mod*(x>=mod);
    x+=mod*(x<0);
}
int mul(int x,int y){
    return 1ll*x*y%mod;
}

除法

在模質數底下,不能整除怎麼辦

\(\frac{x}{y} = z \implies x \equiv y \cdot z \pmod p\)

假設我們有 \(y \cdot b \equiv 1 \pmod p\)

那麼 \( x \cdot b \equiv b \cdot y \cdot z \equiv z \pmod p\) 

也就是說 \( z \equiv x \cdot b \pmod p \)

這樣就可以算了

問題就是要怎麼算出那個 b

有三種方法

  1. 費馬小定理
  2. 酷酷公式
  3. 貝祖定理

模逆元

 費馬小定理

$$ a^{p-1} \equiv 1 \pmod p$$

也就是說 \( a \cdot a^{p-2} \equiv 1 \pmod p\)

代表 \(b = a^{p-2}\)

直接用快速冪做就好了

快速冪

\( a^n = (a^{n/2})^2 \cdot a [a\%2==1] \)

O(logn)

酷酷公式

int inv(int x){
    return x==1?1:mul(mod-mod/x,inv(mod%x));
}

據說是 O(logn)

我不會證但是沒有出包過

實作簡單

貝祖定理

對於所有整數 \(a,b\) 存在無限多組整數 \(x,y\) 滿足 $$ ax + by = gcd(a,b) $$

遞迴

假設我們有了 \( bx' + (b\%a)y' = 1\)

要怎麼推出 \(ax + by = 1\)的解

注意到 \(a\%b = a - \lfloor \frac{a}{b} \rfloor \cdot b\)

$$bx' + (a\%b) y' = 1 $$

$$ bx'  + (a - \lfloor \frac{a}{b} \rfloor b)y' = 1 $$

$$ ay' + b(x' - \lfloor \frac{a}{b} \rfloor y') = 1$$

是唯一能用在合數的模逆元方法

GCD

輾轉相除法

或是有酷酷的內建函式 __gcd 可以用

範例 code

const int mod=998244353;
void add(int& x,int y){
    x+=y;
    x-=mod*(x>=mod);
    x+=mod*(x<0);
}
int mul(int x,int y){
    return 1ll*x*y%mod;
}
int po(int x,int y){
	int z=1;
	while(y){
		if(y&1){
			z=mul(z,x);
		}
		x=mul(x,x);
		y>>=1;
	}
	return z;
}
int inv(int x){
	return po(x,mod-2);
}
int inv(int x){
    return x==1?1:mul(mod-mod%x,inv(mod%x));
}
add(x,1);
x=mul(x,2);
__gcd(3,5);

OJDL 7044

模逆元練習

ARC 158 D

這題太神隨意看題解

質數

判斷質數

從 1 掃到 \( \sqrt n\) ,如果裡面有整數是因數就不是質數,反之則是

其他方法

找到 1 到 n 的所有質數

照上面的作法會是 O(n^1.5) 

改進一下

從 1 到 n 掃過一遍,每次更新他的所有倍數

沒被更新過的就是質數

\( O( \frac{n}{1} + \frac{n}{2} + \dots + \frac{n}{n}) = O(n log(n)) \)

因數篩

小優化

只跑過質數的倍數

\( O( \frac{n}{2} + \frac{n}{3} + \dots )= O(n loglog(n)) \)

上一張的可以用在找出一個數的所有因數

由此也可得 1 到 n 所有數的因數數量和 = O(nlogn)

線性篩

如果能讓每個數都被篩過一次,那就可以 O(n) 算完了

所以我們會想要讓每個合數被他的最小質因數算到

vector<int> vis,pr;
for(int i=2;i<n;i++){
    if(!vis[i]){
        pr.push_back(i);
    }
    for(auto h:pr){
        if(h*i>n){
            break;
        }
        vis[h*i]=1;
        if(i%h==0){
            break;
        }
    }
}

Code

線性篩求歐拉函數

歐拉函數 \(\varphi(n)\) 代表 n 以下有多少數與 n 互質

有積性

code

vector<int> vis,pr,phi;
for(int i=2;i<n;i++){
    if(!vis[i]){
        pr.push_back(i);
        phi[i]=i-1;
    }
    for(auto h:pr){
        if(h*i>n){
            break;
        }
        vis[h*i]=1;
        if(i%h==0){
        	phi[i*h]=h*phi[i];
            break;
        }
        else{
        	phi[i*h]=phi[h]*phi[i];
		}
    }
}

題目

組合

組合數 \(C^n_k\)

算法:主要有三種

  1. \(n \leq 1000: O(n^2) \) Pascal Triangle 
  2. \(n \leq 1000000\) 多次詢問:O(n) 蓋出 frac 表,然後用 $$ C^n_k = \frac{n!}{k! \cdot (n-k)!} $$
  3. (mod 質數) \( n \leq 10^{18}, p \leq 1000\) => Lucas Theorem

在 n 個裡面取 k 個的方法數

AB 跟 BA 好難歸納

如果是 AA 跟 BB 呢

把第偶數個的 A 換成 B,B 換成 A,可以發現答案不變

那麼題目變成不能砍 AA 跟 BB

怎麼做?

他跟 "把 2n 個數配對,不能有一對數相同" 很像

事實上要是他們可以配對那一定找到一個方法刪除連續的兩個值

打架!

結論是只要 A 的個數跟 B 的個數都不超過 N/2 就合法

所以我們可以枚舉不合法的時候的 A 的數量,假設是 k

那麼就是 C(n,k) * 2^(n-k)

就做完了

雖然我當初好像不是這樣寫

一個小細節是這題的 N 很大

多考了一個線性預處理+O(1) 查 C(n,k)

 

你會需要 ifac[i] = fac[i]^(-1)

然後這可以倒著作回來

Lucas theorem

\( C^n_k \equiv \prod_{i=0} C^{n_i}_{k_i} \pmod p \)

\(n_i\) 跟 \(k_i\) 分別是 n 跟 k 轉成 p 進位每一個位的位元

例題:ARC 137 D

排容

我去年居然沒講到這個...

      要計算幾個集合併集的大小,我們要先將所有單個集合的大小計算出來,然後減去所有兩個集合相交的部分,再加回所有三個集合相交的部分,再減去所有四個集合相交的部分,依此類推,一直計算到所有集合相交的部分。

 

copy by wikipedia

式子:

$$\sum_{i=1}^n C^n_i \cdot (-1)^{i+1} \cdot F(i)$$

其中 F(i) 表示選出來 i 個之後滿足條件的個數

上例題壓壓驚 CF 997 C

首先答案 = 橫排滿足條件 + 直排滿足條件 - 都滿足條件

前兩個很好算,比較難的是都滿足條件的那個

可以發現橫排直排都滿足條件,那麼他們顏色是相同的,且所有滿足條件的橫排的顏色都相同

所以假設我們固定其中一個橫排的顏色,那麼可以算出來滿足條件的個數

考慮對橫排個數排容,至少有 i 個橫排滿足條件的選法是

$$C_i^n(3^{n(n-i)}-(2^{n-i} - 1)^n)$$

 

所以都滿足條件的答案是 

$$\sum_{i=1}^n (-1)^{i+1} \cdot C_i^n(3^{n(n-i)}-(2^{n-i} - 1)^n)$$

題單

枚舉 gcd 做排容

AGC 038 C

TIOJ 2287

線代相關

高斯消去

把對角線以下的消掉

這邊原本是 xor basis

但是真的講不完了

所以有興趣的參考 Sam571128 的 blog

如果你要真正的幾何的話我前面有放

喔喔還有這個 CF 1776 I

Made with Slides.com