CF1389E Calendar Ambiguity 题解
题目大意
假设一年有 \(m\) 月,每个月有 \(d\) 天,每周有 \(w\) 天。保证一年的第一天一定是周一。
求 \((x,y)\),满足 \(x<y\) 并且 \(x\) 月 \(y\) 日和 \(y\) 月 \(x\) 日是同一个星期。
\(1\le m,d,w\le 10^9\)。
题目解析
这是我最近写的最短最简洁的 *2200。
由题意得
\[dx+y\equiv dy+x \pmod w
\]
移项
\[(d-1)x\equiv(d-1)y\pmod w
\]
我们设 \(\gcd(d-1,w)=t\),\(a=\dfrac{d-1}{t},p=\dfrac{w}{t}\)。
那么
\[ax\equiv ay\pmod p
\]
由于 \(\gcd(a,p)=1\),所以两边同是乘上 \(a\) 模 \(p\) 的逆元,所以就有
\[x\equiv y\pmod p
\]
然后注意到 \(1\le x<y<\min\{m,d\}\),设 \(lim=\min\{m,d\}\)。
那么如果 \(0<x\bmod p\le lim\bmod p\),那么 \((x,y)\) 的取值就有 \(\lfloor \dfrac{lim}{p}\rfloor\times(\lfloor\dfrac{lim}{p}\rfloor+1)\) 种,否则则有 \(\lfloor \dfrac{lim}{p}\rfloor\times(\lfloor\dfrac{lim}{p}\rfloor-1)\) 种。
int m,d,w,g,p,lim,l,r,ti;
int gcd(int x,int y){ if(!x||!y) return x|y; return gcd(y,x%y); }
void work(){
m=read(); d=read(); w=read();
p=w/gcd(d-1,w); lim=mmin(m,d); l=lim%p; r=p-l; ti=lim/p;
print(1ll*l*ti*(ti+1)/2+1ll*r*ti*(ti-1)/2),pc('\n');
}