51nod 1318 最大公约数与最小公倍数方程组
来源:互联网 发布:软件测试简单吗 编辑:程序博客网 时间:2024/06/06 05:40
原题链接.
题解:
首先分解质因数,gcd就相当于指数的min,lcm就相当于指数的max。
于是问题变成了这样:
给出一坨类似于以下的限制:
min(a,b) = c
max(a,b) = c
问是否有解?
以min为例.
min(a,b) = c
即(a >= c) and (b >= c) and (a = c or b = c)
注意到指数是很小的,c不超过三十。
于是可以把x拆成31(0->30)个组,每个点再拆2个,
a>=c,所以
b>=c,同理。
a = c or b = c,因为已经有了a>=c and b >= c,可以看成a <= c or b <= c,
所以
然后跑过Trjan判断一下有没有
Code:
#include<set>#include<cstdio>#include<algorithm>#define fo(i, x, y) for(int i = x; i <= y; i ++)#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))using namespace std;const int N = 1e6;bool bz[N + 5]; int p[N];char S[N];int T, n, m, a[N], b[N], c[N];int u[50], v[50];int next[N], to[N], final[N], tot;int num[205][105][2], tt, mx;void Shai() { fo(i, 2, N) { if(!bz[i]) p[++ p[0]] = i; fo(j, 1, p[0]) { int k = i * p[j]; if(k > N) break; bz[k] = 1; if(i % p[j] == 0) break; } }}void Fen(int x) { u[0] = 0; for(int i = 1; p[i] * p[i] <= x; i ++) if(x % p[i] == 0) { u[++ u[0]] = p[i], v[u[0]] = 0; while(x % p[i] == 0) x /= p[i], v[u[0]] ++; } if(x > 1) u[++ u[0]] = x, v[u[0]] = 1;}int Q_z(int x, int y) { int z = 0; while(x % y == 0) x /= y, z ++; return z;}set<int> s;void Clear() { fo(i, 1, tot) next[i] = 0; fo(i, 1, tt) final[i] = 0; tot = 0;}void link(int x, int y) { next[++ tot] = final[x], to[tot] = y, final[x] = tot;}int z[N], dfn[N], low[N], ff[N], d[N], bd[N], td;void dg(int x) { bd[x] = 1; d[++ d[0]] = x; dfn[x] = low[x] = ++ td; for(int i = final[x]; i; i = next[i]) { int y = to[i]; if(!dfn[y]) dg(y), low[x] = min(low[x], low[y]); else if(bd[y]) low[x] = min(low[x], dfn[y]); } if(low[x] == dfn[x]) { for(; d[d[0]] != x; d[0] --) ff[d[d[0]]] = x, bd[d[d[0]]] = 0; d[0] --; ff[x] = x; bd[x] = 0; }}bool pd() { td = 0; fo(i, 1, tt) low[i] = 0, dfn[i] = 0; fo(i, 1, tt) if(!dfn[i]) dg(i); fo(i, 1, n) fo(j, 0, mx) { if(ff[num[i][j][0]] == ff[num[i][j][1]]) { return 0; } } return 1;}char get() { char c = ' '; for(;c != 'G' && c != 'L'; c = getchar()); return c;}int main() { Shai(); for(scanf("%d", &T); T; T --) { s.clear(); scanf("%d %d", &n, &m); fo(i, 1, m) { S[i] = get(); scanf("%d %d %d", &a[i], &b[i], &c[i]); a[i] ++; b[i] ++; Fen(c[i]); fo(i, 1, u[0]) s.insert(u[i]); } int ans = 1; while(!s.empty()) { int x = *s.begin(); s.erase(x); mx = 0; fo(i, 1, m) z[i] = Q_z(c[i], x), mx = max(mx, z[i]); tt = 0; fo(i, 1, n) fo(j, 0, mx) num[i][j][0] = ++ tt, num[i][j][1] = ++ tt; fo(i, 1, n) fo(j, 0, mx - 1) link(num[i][j][0], num[i][j + 1][0]); fo(i, 1, n) fo(j, 1, mx) link(num[i][j][1], num[i][j - 1][1]); Clear(); fo(i, 1, m) { if(S[i] == 'G') { fo(j, 0, z[i] - 1) { link(num[a[i]][j][0], num[a[i]][j][1]); link(num[b[i]][j][0], num[b[i]][j][1]); } fo(j, z[i], mx) { link(num[a[i]][j][1], num[b[i]][z[i]][0]); link(num[b[i]][j][1], num[a[i]][z[i]][0]); } } else { fo(j, z[i], mx) { link(num[a[i]][j][1], num[a[i]][j][0]); link(num[b[i]][j][1], num[b[i]][j][0]); } fo(j, 0, z[i] - 1) { link(num[a[i]][j][0], num[b[i]][z[i] - 1][1]); link(num[b[i]][j][0], num[a[i]][z[i] - 1][1]); } } } ans &= pd(); if(!ans) break; } if(ans) printf("Solution exists\n"); else printf("Solution does not exist\n"); }}
阅读全文
1 0
- 51nod 1318 最大公约数与最小公倍数方程组
- 51nod 1318 最大公约数与最小公倍数方程组 2-SAT+数学
- 51nod 最大公约数 & 最小公倍数
- 51 nod 最大公约数的最小公倍数
- 求最大公约数与最小公倍数
- 最大公约数与最小公倍数问题
- 求最大公约数与最小公倍数
- 最大公约数与最小公倍数
- 最大公约数与最小公倍数
- 求最大公约数与最小公倍数
- 最大公约数 与 最小公倍数
- 最大公约数与最小公倍数源码
- 最小公倍数与最大公约数
- 最大公约数与最小公倍数
- 最大公约数与最小公倍数
- 最大公约数与最小公倍数
- 最小公倍数与最大公约数
- 最大公约数与最小公倍数
- Xrecyclerview的使用(上拉刷新,下拉加载)
- bzoj 2456 mode 模拟? 解题报告
- php中trait的使用
- [博弈] Codeforces Gym101190 NEERC2016G. Game on Graph
- 中文分词算法笔记
- 51nod 1318 最大公约数与最小公倍数方程组
- 【Nginx+Keepalived】组建高可用负载平衡Web server集群
- C和C++中标准输入中遇到的问题
- Educational Codeforces Round 28 题解
- 【DFS】NOIP2014Day1T2[联合权值]题解
- 【2014acm西安现场赛】K
- <Android 进阶(二)> 自定义View之Dota2能力雷达图
- 算法设计 第二次上机 Subway
- SQL中 % ,_,【】,【^】通配符的的使用