1. 程式人生 > 其它 >2020 ICPC 瀋陽站 I - Rise of Shadows 題解

2020 ICPC 瀋陽站 I - Rise of Shadows 題解

卡了我三個小時的數論簽到題
題面看這裡

題目大意

給你一個一天有 \(H\)​​​​​​​ 小時、一小時有 \(M\)​​​​​​​​ 分鐘的表和一個正整數 \(A\)​,問一天內有多少個整數時刻,使得分針與時針的夾角小於等於 \(\displaystyle\frac{2\pi A}{HM}\)​。

題目分析

分針轉速 \(w_1=\displaystyle \frac{2\pi}{M}\)​​​​​,時針轉速 \(w_2=\displaystyle\frac{2\pi}{HM}\)​​​​,當前時刻為 \(T\)​​​​;

一天有 \(HM\)​​​​ 個整數時刻,即 \(T\in[0,HM)\)​​​​;

於是對於每一個時刻,我們判斷一下兩個指標的夾角 \(\theta\)

​​​​​ 是否小於等於 \(\displaystyle\frac{2\pi A}{HM}\)​​​​​​​​​ ,滿足就貢獻加加,最後輸出總貢獻即可。

方法一:數論

顯然有:

\[\theta=(w_1-w_2)T=\displaystyle\frac{2\pi(H-1)T}{HM}​ \]

注意到 \(\theta\in[0,2\pi]\)​​,所以還要對 \(2\pi\)​​ 取個模(分針轉一圈又轉回來了),即:

\[\theta=\displaystyle\frac{2\pi(H-1)T}{HM}\mod{2\pi} \]

同時因為兩個指標之間的夾角可以選到兩個數值,逆時針轉有一個夾角,順時針轉有一個夾角,這裡我們肯定是選更小的角來判斷是否滿足條件,即最終我們要求的是:

\[\sum_{T=0}^{HM}[\ \min(\theta,2\pi-\theta)\leq\frac{2\pi A}{HM}\ ] \]

可以轉化為:

\[\sum_{T=0}^{HM}[\ \theta\leq\frac{2\pi A}{HM}\or\theta\ge2\pi-\frac{2\pi A}{HM}\ ] \]

\(\theta=\displaystyle\frac{2\pi(H-1)T}{HM}\mod{2\pi}\) 代入並化簡得:

\[\sum_{T=0}^{HM}[\ T(H-1)\mod{HM}\leq A\or T(H-1)\mod{HM}\geq HM-A\ ] \]

此時我們其實就可以把 \(HM\)

​​​ 看作是 \(2\pi\)​​​,\(H-1\)​​ 看作是每過一個時刻兩個指標夾角的變化量。

\(A=HM/2\)​​​ 時,問題等價於”一天內有多少個整數時刻,使得分針與時針的夾角小於等於 \(\pi\)​​“,顯然每個時刻都滿足(如果順時針看夾角大於 \(\pi\)​​,那逆時針看一定小於,反之亦然),此時答案為 \(HM\)​​;

\(A\neq HM/2\)​ 時,若有 \(T(H-1)\mod{HM}\leq A\)​,則一定不會有 \(T(H-1)\mod{HM}\geq HM-A\)​​​​,所以答案就是這兩部分的貢獻相加。

我們令 \(G=\gcd(H-1,HM)\)

先計算式子的左邊:

\[\sum_{T=0}^{HM}[\ T(H-1)\mod{HM}\leq A\ ] \]

\(G=1\)​​​​ 時 ,因為 \(T\in[0,HM)\)​​​​,由同餘的性質可得 \(T(H-1)\mod{HM}\)​​​​ 一定取遍了 \(0\sim HM\)​​​​ 的每個數,即構成一個模 \(HM\)​​​​ 的完全剩餘系,此時這部分的貢獻就是 \(A+1\)​​​​​。

\(G\neq1\)​​​​ 時,我們利用同餘的另一個性質: \(\displaystyle ac\equiv bc\pmod d\iff a\equiv b\pmod{\frac{d}{(c,d)}}\)​​​​,把式子轉化為:

\[\sum_{T=0}^{HM}[\ \frac{T(H-1)}{G}\mod{\frac{HM}{G}}<=\lfloor\frac AG\rfloor\ ] \]

相當於我們把 \(T\in[0,HM)\)​​​​​ 平均分成了 \(G\)​​​​​ 段,且每段的 \(T\mod\displaystyle\frac{HM}G\)​​​​​ 都取到了 \(0\sim \displaystyle\frac{HM}G\)​​​​​ 的每個數,同時有 \(\gcd(\displaystyle\frac{H-1}G,\displaystyle\frac{HM}G)=1\)​​​​​,因此這裡的每一小段,其實就等價於上面 \(G=1\)​​​​​ 的情況,只是 \(T\)​​​ 的範圍和模數變了下而已,此時每一小段都造成了 \(\displaystyle \lfloor\frac AG\rfloor+1\)​​​ 的貢獻,總貢獻就是 \(G*(\displaystyle \lfloor\frac AG\rfloor+1)\)​​​​​​​。

再看式子右邊:

\[\sum_{T=0}^{HM}[\ T(H-1)\mod{HM}\geq HM-A\ ] \]

同樣地,當 \(G=1\)​​​​ 時,跟上面一樣分析一波,發現其實是等價的(這裡顯然具有對稱性),只不過因為 \(T\)​​​​ 不能取到 \(HM\)​​​​,所以貢獻只有 \(A\)\([HM-A,HM-1]\) 共有 \(A\) 個數)​​​​。

\(G\neq1\) 時,也同上,把 \(T\) 分成 \(G\) 段,總貢獻是 \(G*\displaystyle \lfloor\frac AG\rfloor\)

因此答案就是:\(G*(\displaystyle 2\lfloor\frac AG\rfloor+1)\)

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long H,M,A;
	cin >> H >> M >> A;
	if(H*M==A*2){
		cout << H*M;
	}
	else {
		long long G=__gcd(H-1,H*M);
		cout << G*(2*(A/G)+1);
	}
}

方法二:類歐幾里得

待填坑~~