[HDU 5032 Always Cook Mushroom] 离线+极角排序+树状数组

题目

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;
}

你可能感兴趣的:([HDU 5032 Always Cook Mushroom] 离线+极角排序+树状数组)