CF1519E Off by One
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;
}