题目
http://acm.hdu.edu.cn/showproblem.php?pid=5032
分析
离线+按斜率排序+树状数组
把所有询问离线,把所有1000*1000个点和所有询问都按照斜率排序,按x建立树状数组
枚举每个询问,每次把斜率小于当前询问的点都加入树状数组,查询时求和即可
代码
/************************************************** * Problem: HDU 5032 * Author: clavichord93 * State: Accepted **************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int MAX_N = 1005; const int MAX_M = 100005; struct Query { int a, b, x, id; bool operator < (const Query &t) const { return (long long)a * t.b - (long long)b * t.a > 0; } }; struct Comparator { bool operator () (const pair<int, int> &a, const pair<int, int> &b) { return (long long)a.first * b.second - (long long)a.second * b.first > 0; } }; int A, B, m; long long c[MAX_N]; long long ans[MAX_M]; Query query[MAX_M]; int cntPoint; pair<int, int> point[MAX_N * MAX_N]; long long det(int x1, int y1, int x2, int y2) { return (long long)x1 * y2 - (long long)y1 * x2; } inline int lowbit(int i) { return i & (-i); } void add(int x, long long val) { for (int i = x; i <= 1000; i += lowbit(i)) { c[i] += val; } } long long get(int x) { long long ret = 0; for (int i = x; i; i -= lowbit(i)) { ret += c[i]; } return ret; } int main() { #ifdef LOCAL_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif int T; scanf("%d", &T); for (int i = 1; i <= 1000; i++) { for (int j = 1; j <= 1000; j++) { point[cntPoint++] = make_pair(i, j); } } sort(point, point + cntPoint, Comparator()); //for (int i = 0; i < cntPoint; i++) { //printf("%d %d\n", point[i].first, point[i].second); //} //printf("\n"); for (int cas = 1; cas <= T; cas++) { scanf("%d %d", &A, &B); scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d %d %d", &query[i].a, &query[i].b, &query[i].x); query[i].id = i; } sort(query, query + m); memset(c, 0, sizeof(c)); for (int i = 0, j = 0; i < m; i++) { while (j < cntPoint && det(point[j].first, point[j].second, query[i].a, query[i].b) >= 0) { add(point[j].first, (point[j].first + A) * (point[j].second + B)); j++; } ans[query[i].id] = get(query[i].x); } printf("Case #%d:\n", cas); for (int i = 0; i < m; i++) { printf("%I64d\n", ans[i]); } } return 0; }