AtCoder AGC031F Walk on Graph (图论、数论)
題目鏈接
https://atcoder.jp/contests/agc031/tasks/agc031_f
題解
這題真是太神仙了……
首先我們轉化一下問題,倒著來做,一開始有一個數\(0\), 每次走過一條邊該數變為乘以\(2\)再加上這條邊的邊權。
我們用\((u,x)\)代表一個狀態,表示當前在點\(u\),該數值為\(x\), \(x\)始終在\(\mod p\)意義下定義,\(p\)為模數。
假設\(u\)點有一條邊連向\(v\)邊權為\(w\), 則\((u,x)\)可以變成\((v,2x-w)\)(下用\(\Rightarrow\)表示),然后\((v,2x-w)\Rightarrow(u,4x-3w),(u,4x-3w)\Rightarrow(v,8x-7w),...\)
但是由于\(p\)是奇數,存在\(k>1\)使\(2^k\equiv 1(\mod p)\), 這個序列是循環的,由\((u,x)\)最終依然會到達\((u,x)\). 也就是說,我們可以認為這個遞推關系是雙向的,\((u,x)\Leftrightarrow (v,2x-w)\Leftrightarrow (u,4x-3w)\Leftrightarrow ...\)
這時,不要往\(2\)的冪的方向思考而一去不復返。考慮這個遞推序列的前三步: \((u,x)\Leftrightarrow (u,4x-3w)\)
如果有兩條連接的邊分別是\(w_1,w_2\), 則\((u,x)\Leftrightarrow (u,4x-3w_1) \Leftrightarrow (u,4x-3w_2)\). 又因為\(4\)在\(\mod p\)意義下有逆元,故\(4x\)可以代表任何數,即\((u,x)\Leftrightarrow (u,x\pm 3(w_1-w_2))\).
考慮一個點相連的那些邊,由數論的基本知識可得,\((u,x)\Leftrightarrow (u,x+kt_u)\) (\(k\)為整數),其中\(t_u=\gcd(3g_u,p)\), \(g_u\)為與\(u\)相連所有邊權的\(\gcd\). 即所有模\(t_u=\gcd(3g_u,p)\)同余的\(x\), \((u,x)\)的狀態是一樣的。
再進一步說,考慮不同的點,\((u,x)\Leftrightarrow (v,2x+w)\), \(u\)循環節為\(t_u\)導致\(v\)具有長度為\(2t_u\)的循環節,和其本身的取\(\gcd\)得\(\gcd(t_u,2t_v)=\gcd(t_u,t_v)\) (\(2\)可以去掉是因為\(2\)與\(3g_u\)互質因而與\(t_u\)互質)。由于整個圖是聯通的,這可以擴展到所有點,也就是對于所有\(u,x\)有\((u,x)\Leftrightarrow (u,x+T)\), 其中\(T=\gcd^n_{u=1}t_u=\gcd(3\gcd^m_{i=1}w_i,p)\). 我們令\(G=\gcd^m_{i=1}w_i\). 顯然\(T=G\)或\(T=3G\).
整理一下,同一點所有模\(T\)同余的狀態是一樣的,而所有邊權是模\(G\)同余的,且\(T=G\)或\(T=3G\).
這樣,我們可以把題目中的\(p\)直接改成\(T\), 不會對答案有任何影響。下面我們用\(p\)來代表\(T\).
注: 這里之所以我們只取了\((4x-3y)\)這一項而沒有繼續深入下去依然能得到正確的結論的原因是對任何\(k\in \mathbb{N}\), \((u,2^{2k}x+(2^{2k}-1)w)\), 而\(3|(2^{2k}-1)\).
既然所有邊權是模\(G\)同余的,我們就可以設\(w_i=c_iG+z\), 其中\(0\le z\lt G\)是一個對于所有的邊\(i\)都一樣的數。
這個邊權帶常數\(z\)看上去很不優美,我們想辦法把它消掉!我們把所有的當前數值\(x\)都增加\(z\), 并把所有的邊權都減少\(z\). 改變后的值記為\(x'\), 那么現在的一次游走將會是: \(x'-z=x\rightarrow (2x+c_iG+z)=(2(x+z)+c_iG)-z=(2x'+c_iG)-z\), 也就是說\(x'\)經過一次操作會變成\(2x'+c_iG\), \(z\)的余數沒了,其余操作沒有變化!
于是我們執行把數值\(x\)增加\(z\)同時把邊權減少\(z\)的操作,現在我們認為\(w_i=c_iG\),且詢問的是\((t,z)\)與\((s,z+r)\)是否可達。
因為\(w_i=c_iG\),故\((u,x)\Leftrightarrow (u,4x+3c_iG)\Leftrightarrow (u,4x)\), 且因為邊權全部是\(G\)的倍數,在\(\mod 3G\)意義下只有\(3\)種取值,即可以認為\(c_i=0,1,2\). 那每個狀態就可以表示成\((u,2^jx+kG)\)的形式,其中\(0\le j\lt 2,0\le k\lt 3\).
也就是說,對于每個點,我們只有\(6\)種狀態有用!
然后的做法就很顯然了,我們建出這\(6n\)個狀態,對于每一條輸入的邊,操作權值之后把相應的狀態用并查集縮起來。
對于詢問,我們想要的是\((t,z)\)和\((s,z+r)\)是否聯通。枚舉\(j\mod 2\)與\(k\), 我們得到\(2^jz+kG\equiv z+r(\mod p)\). 我們需要判斷是否存在\(j\)滿足\(2^jz\equiv z+r-kG(\mod p)\), 這個對于每個\(j\)預處理一下\(2^jz\)記錄下來奇偶即可。若存在且\((t,0,0)\)和\((s,j,k)\)這兩個狀態聯通,則答案是YES, 否則是NO.
時間復雜度\(O(6(n+m+q)\alpha(n)+p)\).
代碼
#include<bits/stdc++.h> #define llong long long #define mkpr make_pair #define riterator reverse_iterator using namespace std;inline int read() {int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f; }const int N = 5e4; const int mxP = 1e6; struct AEdge {int u,v,w; } ae[N+3]; int uf[N*6+3]; bool ispw2[mxP+3][2]; int n,m,q,p,g;int gcd(int x,int y) {return y==0?x:gcd(y,x%y);}int getid(int x,int j,int k) {return (j*3+k)*n+x;} int findfa(int u) {return u==uf[u]?u:uf[u]=findfa(uf[u]);} void unionfa(int u,int v) {int x = findfa(u),y = findfa(v);if(x!=y) {uf[x] = y;} }int main() {scanf("%d%d%d%d",&n,&m,&q,&p); g = p;for(int i=1; i<=n*6; i++) uf[i] = i;for(int i=1; i<=m; i++){scanf("%d%d%d",&ae[i].u,&ae[i].v,&ae[i].w);g = gcd(g,abs(ae[i].w-ae[1].w));}p = gcd(p,3*g);int z = ae[1].w%g;for(int i=1; i<=m; i++){int w = (ae[i].w-z)/g%3,u = ae[i].u,v = ae[i].v;for(int j=0; j<2; j++) for(int k=0; k<3; k++){unionfa(getid(u,j,k),getid(v,j^1,(k+k+w)%3));unionfa(getid(v,j,k),getid(u,j^1,(k+k+w)%3));}}for(int i=0,x=z; i<p; i++,x=(x<<1)%p) ispw2[x][i&1] = true;while(q--){int u,v,l; scanf("%d%d%d",&u,&v,&l); bool ans = false;for(int j=0; j<2; j++) for(int k=0; k<3; k++){int tmp = (z+l+(3-k)*g)%p;if(ispw2[tmp][j]){int uu = findfa(getid(v,0,0)),vv = findfa(getid(u,j,k));if(uu==vv) {ans = true; break;}}}if(ans==true) puts("YES"); else puts("NO");}return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的AtCoder AGC031F Walk on Graph (图论、数论)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AtCoder AGC031E Snuk
- 下一篇: AtCoder AGC033F Addi