题目链接:点击打开链接
思路:统计区间和, 我们想到了树状数组, 离散化后, 枚举第一个人选取的x坐标, 用两个树状数组,以y坐标为下标建树, 一个表示当前左边的情况, 一个表示右边的情况, 再枚举当前垂直线上的每个点, 可以用树状数组快速统计结果, 该题题意挺难理解的, 要求输出第一个人的最小得分的最大值ans, 还有就是当第一个人取ans时第二个人的可能得分。时间复杂度O(nlogn)
细节参见代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include <cmath> #include <set> #include <list> #include <deque> #include <map> #include <queue> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long ll; typedef long double ld; const ld eps = 1e-9, PI = 3.1415926535897932384626433832795; const int mod = 1000000000 + 7; const int INF = 0x3f3f3f3f; const int seed = 131; const ll INF64 = ll(1e18); const int maxn = 2e5 + 10; int T,n,m,bit1[maxn],bit2[maxn],x[maxn],y[maxn]; struct node { int x, y; node(int x=0, int y=0):x(x), y(y) {} bool operator < (const node& rhs) const { if(x != rhs.x) return x < rhs.x; else return y < rhs.y; } }a[maxn]; int sum(int bit[], int x) { int ans = 0; while(x > 0) { ans += bit[x]; x -= x & -x; } return ans; } void add(int bit[], int x, int d) { while(x <= n) { bit[x] += d; x += x & -x; } } void init(int n) { for(int i = 0; i <= n + 10; i++) { bit1[i] = bit2[i] = 0; } } vector<int> g[maxn]; int main() { while(~scanf("%d",&n) && n) { init(n + 10); int cnt = 0; for(int i = 1; i <= n; i++) { scanf("%d%d",&a[i].x,&a[i].y); x[cnt] = a[i].x; y[cnt++] = a[i].y; } set<int> G; set<int> :: iterator it; sort(x, x+cnt); sort(y, y+cnt); int cnt_x = unique(x, x+cnt) - x; int cnt_y = unique(y, y+cnt) - y; for(int i = 0; i <= cnt_x; i++) g[i].clear(); for(int i = 1; i <= n; i++) { int id = lower_bound(y, y+cnt_y, a[i].y) - y + 1; int id2 = lower_bound(x, x+cnt_x, a[i].x) - x + 1; add(bit2, id, 1); g[id2].push_back(id); } int ans = 0; for(int i = 1; i <= cnt_x; i++) { int len = g[i].size(); for(int j = 0; j < len; j++) { int id = g[i][j]; add(bit2, id, -1); } int hehe = INF; for(int j = 0; j < len; j++) { int id = g[i][j]; int cur = sum(bit2, cnt_y) - sum(bit2, id); cur += sum(bit1, id-1); hehe = min(hehe, cur); } if(ans < hehe) { ans = hehe; G.clear(); for(int j = 0; j < len; j++) { int id = g[i][j]; int cur = sum(bit2, cnt_y) - sum(bit2, id); cur += sum(bit1, id-1); if(cur == ans) { int res = sum(bit1, cnt_y) - sum(bit1, id); res += sum(bit2, id-1); G.insert(res); } } } else if(ans == hehe) { for(int j = 0; j < len; j++) { int id = g[i][j]; int cur = sum(bit2, cnt_y) - sum(bit2, id); cur += sum(bit1, id-1); if(cur == ans) { int res = sum(bit1, cnt_y) - sum(bit1, id); res += sum(bit2, id-1); G.insert(res); } } } for(int j = 0; j < len; j++) { int id = g[i][j]; add(bit1, id, 1); } } printf("Stan: %d; Ollie:", ans); for(it = G.begin(); it != G.end(); ++it) { printf(" %d",*it); } printf(";\n"); } return 0; }