poj3109 Inner Vertices

思路:

树状数组 + 扫描线。

实现:

 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 const int MAXN = 100005;
 6 int x[MAXN], y[MAXN], bit[MAXN], cnt[MAXN], now[MAXN], n;
 7 bool vis[MAXN];
 8 vector<int> lines[MAXN];
 9 int lowbit(int x) { return x & -x; }
10 void add(int i, int x)
11 {
12     while (i <= MAXN) { bit[i] += x; i += lowbit(i); }
13 }
14 int sum(int i)
15 {
16     int ans = 0;
17     while (i) { ans += bit[i]; i -= lowbit(i); }
18     return ans;
19 }
20 int compress(int * a)
21 {
22     vector<int> v(a, a + n);
23     sort(v.begin(), v.end());
24     v.erase(unique(v.begin(), v.end()), v.end());
25     for (int i = 0; i < n; i++) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;
26     return v.size();
27 }
28 int main()
29 {
30     scanf("%d", &n);
31     for (int i = 0; i < n; i++) scanf("%d %d", x + i, y + i);
32     int X = compress(x), Y = compress(y);
33     for (int i = 0; i < n; i++) { lines[x[i]].push_back(y[i]); cnt[y[i]]++; }
34     int ans = 0;
35     for (int i = 1; i <= X; i++)
36     {
37         sort(lines[i].begin(), lines[i].end());
38         for (int j = 0; j < lines[i].size() - 1; j++) ans += sum(lines[i][j + 1] - 1) - sum(lines[i][j]);
39         for (int j = 0; j < lines[i].size(); j++)
40         {
41             int tmp = lines[i][j];
42             if (!vis[tmp]) { vis[tmp] = true; add(tmp, 1); }
43             now[tmp]++;
44             if (now[tmp] == cnt[tmp]) add(tmp, -1); 
45         }
46     } 
47     printf("%d
", ans + n);
48     return 0;
49 }
原文地址:https://www.cnblogs.com/wangyiming/p/8457086.html