CF1519E Off by One
阿新 • • 發佈:2021-12-16
https://www.luogu.com.cn/problem/CF1519E
可以考慮連邊
\((\frac{a_i}{b_i}+1)-(\frac{c_i}{d_i})\)
\((\frac{a_i}{b_i})-(\frac{c_i}{d_i}+1)\)
然後跑最大匹配
code:
#include<bits/stdc++.h> #define N 400050 #define ll long long #define pii pair<ll, ll> using namespace std; map<pii, int> mp; ll gcd(ll x, ll y) { return y? gcd(y, x % y) : x; } int tot; int get(ll x, ll y) { ll d = gcd(x, y); x /= d, y /= d; pii o = make_pair(x, y); if(!mp[o]) mp[o] = ++ tot; return mp[o]; } struct edge { int v, c, nxt; } e[N << 1]; int p[N], eid; void init() { memset(p, -1, sizeof p); eid = 0; } void insert(int u, int v, int c) { //printf("%d --> %d %d\n", u, v, c); e[eid].v = v; e[eid].c = c; e[eid].nxt = p[u]; p[u] = eid ++; } int vis[N], match[N], n; vector<pii > ans; void dfs(int u) { vis[u] = 1; for(int i = p[u]; i + 1; i = e[i].nxt) { int v = e[i].v, id = e[i].c; if(!id) continue; e[i].c = e[i ^ 1].c = 0; if(!vis[v]) dfs(v); if(match[v]) ans.push_back(make_pair(match[v], id)), match[v] = 0; else if(match[u]) ans.push_back(make_pair(match[u], id)), match[u] = 0; else match[u] = id; } } int main() { init(); scanf("%d", &n); for(int i = 1; i <= n; i ++) { int a, b, c, d; scanf("%d%d%d%d", &a, &b, &c, &d); int u = get(1ll * (a + b) * d, 1ll * b * c); int v = get(1ll * a * d, 1ll * (c + d) * b); insert(u, v, i), insert(v, u, i); } for(int i = 1; i <= tot; i ++) if(!vis[i]) dfs(i); printf("%d\n", (int)ans.size()); for(auto i : ans) printf("%d %d\n", i.first, i.second); return 0; }