【LOJ】#2069. 「SDOI2016」齿轮
2018-08-25 15:27
232 查看
题解
我一开始还努力想这道题是不是有坑,被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】#2067. 「SDOI2016」硬币游戏
- 【LOJ】#2068. 「SDOI2016」探险路线
- 【LOJ】#2035. 「SDOI2016」征途
- 【LOJ】#2032. 「SDOI2016」游戏
- 【LOJ】#2070. 「SDOI2016」平凡的骰子
- 【LOJ】#2031. 「SDOI2016」数字配对
- [Sdoi2016]齿轮
- 【LOJ】 #2033. 「SDOI2016」生成魔咒
- [SDOI2016] BZOJ4602 齿轮-dfs-带权并查集-数论逆元-质因数分解
- 【LOJ】#2065. 「SDOI2016」模式字符串
- LOJ刷题记录:2030-2035(SDOI2016)
- [SDOI2016]齿轮
- 【LOJ】#2066. 「SDOI2016」墙上的句子
- HDU 2069 Coin Change
- “变速齿轮”研究手记
- HTML5 Canvas 绘制齿轮【每日一段代码34】
- 【搜索】齿轮
- CSS3——齿轮转动
- Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果
- loj 1063(求割点个数)