我們把所有點分成四類
$A_{0,0},A_{0,1},A_{1,0},A_{1,1}$
發現如果$A_{0,0}+A_{1,1} > 0$並且$A_{0,1}+A_{1,0} > 0$或者$A_{0,0}+A_{0,1} > 0$並且$A_{1,0} + A_{1,1} > 0$,這樣可以直接得出答案
剩下的情況就是四種只存在一種的情況,這種情況把所有坐標縮小一倍,相等關系不變。
於是復雜度$O(nlog(n^2))$
這個想法根本沒想到 感覺很奇妙 不過似乎有一種2-sat解法 可惜比賽的時候2-sat忘光了
在宿舍里打比賽果然手速減半 又掉分了

#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 5; int n; int x[maxn], y[maxn], cnt[2][2]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d%d", &x[i], &y[i]); } while(1) { int s = 0; memset(cnt, 0, sizeof(cnt)); for(int i = 1; i <= n; ++i) { ++cnt[x[i] & 1][y[i] & 1]; } vector<int> ans; if(cnt[0][0] + cnt[1][1] > 0 && cnt[0][1] + cnt[1][0] > 0) { for(int i = 1; i <= n; ++i) { if(x[i] + y[i] & 1) { ans.push_back(i); } } printf("%d\n", ans.size()); for(auto x : ans) { printf("%d ", x); } return 0; } if(cnt[0][0] + cnt[0][1] > 0 && cnt[1][0] + cnt[1][1] > 0) { for(int i = 1; i <= n; ++i) { if(x[i] & 1) { ans.push_back(i); } } printf("%d\n", ans.size()); for(auto x : ans) { printf("%d ", x); } return 0; } for(int i = 1; i <= n; ++i) { x[i] >>= 1; y[i] >>= 1; } } return 0; }