codeforces1028F: Make Symmetrical
有个结论,一个以原点为圆心的圆,那么这个圆上的整点非常少。
然后我们就可以记录每个环上面的点,加入和删除的时候,就暴力的把答案都统计出来。
O(1)进行询问。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define M 200010 5 #define num(x, y) 1ll * x * x + 1ll * y * y 6 map<LL, int> mp; 7 int tot; 8 vector<pair<int, int> > a[M]; 9 map<pair<int, int>, int> Ans; 10 inline int Get(LL p) { 11 if(mp.find(p) == mp.end()) { 12 mp[p] = ++ tot; 13 return tot; 14 } 15 return mp[p]; 16 } 17 int main() { 18 int q; 19 scanf("%d", &q); 20 int cnt = 0; 21 while(q --) { 22 int op, x, y; 23 scanf("%d%d%d", &op, &x, &y); 24 int pos = Get(num(x, y)); 25 if(op == 1) { 26 for(int i = 0; i < a[pos].size(); ++ i) { 27 int X = a[pos][i].first + x, Y = a[pos][i].second + y; 28 int GCD = __gcd(X, Y); 29 X /= GCD; Y /= GCD; 30 Ans[make_pair(X, Y)] += 2; 31 } 32 a[pos].push_back(make_pair(x, y)); 33 int GCD = __gcd(x, y); 34 x /= GCD; y /= GCD; 35 Ans[make_pair(x, y)] ++; 36 ++ cnt; 37 } 38 else if(op == 2) { 39 vector<pair<int, int> > :: iterator it; 40 for(it = a[pos].begin(); it != a[pos].end(); ++ it) { 41 if(*it == make_pair(x, y)) { 42 a[pos].erase(it); 43 break; 44 } 45 } 46 for(int i = 0; i < a[pos].size(); ++ i) { 47 int X = a[pos][i].first + x, Y = a[pos][i].second + y; 48 int GCD = __gcd(X, Y); 49 X /= GCD; Y /= GCD; 50 Ans[make_pair(X, Y)] -= 2; 51 } 52 int GCD = __gcd(x, y); 53 x /= GCD; y /= GCD; 54 Ans[make_pair(x, y)] --; 55 -- cnt; 56 } 57 else { 58 int GCD = __gcd(x, y); 59 x /= GCD; y /= GCD; 60 printf("%d\n", cnt - Ans[make_pair(x, y)]); 61 } 62 } 63 }