Always Cook Mushroom

HDOJ-5032-Always Cook Mushroomopen in new window

分析

示意图:

极角序统计答案。

实现

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 1010, M = 100010;
struct node {
    int x, y;
    double k;
    LL res;
};
int A, B, m;
node a[N * N], rec[M];
LL c[N];

bool cmp1 (const node& a, const node& b) {
    return a.k < b.k;
}
bool cmp2 (const node& a, const node& b) {
    return a.y < b.y;
}
int lowbit (int x) {
    return x & -x;
}
void add (int idx, LL val) {
    while (idx <= 1000) {
        c[idx] += val;
        idx += lowbit(idx);
    }
}
LL sum (int idx) {
    LL res = 0;
    while (idx >= 1) {
        res += c[idx];
        idx -= lowbit(idx);
    }
    return res;
}

int main () {
    int idx = 0;
    for (int i = 1; i <= 1000; ++ i)
        for (int j = 1; j <= 1000; ++ j)
            a[++ idx] = { i, j, (double)j / i, 0 };
    sort(a + 1, a + idx + 1, cmp1); // 按斜率由小到大排序

    int _;
    scanf("%d", &_);
    for (int T = 1; T <= _; ++ T) {
        memset(c, 0, sizeof(c));

        scanf("%d%d%d", &A, &B, &m);
        for (int i = 1, a, b, x; i <= m; ++ i) {
            scanf("%d%d%d", &a, &b, &x);
            rec[i] = { x, i, (double)b / a, 0 }; // 离线
        }

        sort(rec + 1, rec + m + 1, cmp1); // 按斜率由小到大排序
        int ptr = 1;
        for (int i = 1; i <= m; ++ i) {
            while (a[ptr].k <= rec[i].k) {
                add(a[ptr].x, (LL)(a[ptr].x + A) * (a[ptr].y + B));
                ++ ptr;
            }
            rec[i].res = sum(rec[i].x);
        }

        sort(rec + 1, rec + m + 1, cmp2);
        printf("Case #%d:\n", T);
        for (int i = 1; i <= m; ++ i)
            printf("%lld\n", rec[i].res);
    }
    return 0;
}
最后修改于: