【LOJ】#2069. 「SDOI2016」齒輪
阿新 • • 發佈:2018-08-25
utc name end ble 帶權並查集 double rst getchar() als
題解
我一開始還努力想這道題是不是有坑,被SDOI折磨到我覺得不能有那麽水的題在……
就是帶權並查集維護一下兩點間距離,如果新加一條邊兩個點在同一集合,看看已有的路徑和新加的路徑是否相等
乘積可以在模意義下維護,多隨機幾個模數就行
代碼
#include <bits/stdc++.h> #define enter putchar(‘\n‘) #define space putchar(‘ ‘) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 1000005 #define mo 999999137 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 + c - ‘0‘; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar(‘-‘);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } int T; int Mod[5] = {1926365417,1514229737,1066816031,1224683249,1091059271}; int N,M; int u[10005],v[10005],x[10005],y[10005],inv[105]; int fa[1005],dis[1005]; int MOD; int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } int getfa(int u) { if(fa[u] == u) return u; else { int res = getfa(fa[u]); dis[u] = mul(dis[fa[u]],dis[u]); fa[u] = res; return res; } } bool check(int c) { MOD = c; inv[1] = 1; for(int i = 2 ; i <= 100 ; ++i) { inv[i] = mul(inv[MOD % i],MOD - MOD / i); } for(int i = 1 ; i <= N ; ++i) { fa[i] = i;dis[i] = 1; } for(int i = 1 ; i <= M ; ++i) { int up = x[i],down = inv[abs(y[i])]; if(x[i] < 0) up = MOD - up; if(y[i] < 0) down = MOD - down; if(getfa(u[i]) == getfa(v[i])) { int r = mul(fpow(dis[v[i]],MOD - 2),dis[u[i]]); if(r != mul(up,down)) return false; } else { int r = mul(mul(up,down),fpow(dis[u[i]],MOD - 2)); int t = getfa(u[i]); fa[t] = v[i];dis[t] = r; } } return true; } bool Solve() { read(N);read(M); for(int i = 1 ; i <= M ; ++i) { read(u[i]);read(v[i]);read(x[i]);read(y[i]); } for(int i = 0 ; i <= 4 ; ++i) { if(!check(Mod[i])) return false; } return true; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(T); for(int i = 1 ; i <= T ; ++i) { printf("Case #%d: ",i); if(Solve()) puts("Yes"); else puts("No"); } return 0; }
【LOJ】#2069. 「SDOI2016」齒輪