HDU Ads Proposal 【樹狀數組】

題意:N個customer,M個advertisement,每個ad只屬於一個cus,每個ad都有一個點擊量和一個長度值。現在對於每個詢問,求出所有cus的前k大點擊量的廣告的總長度。


對於每個ad,求出他在所屬的cus裏面的排名,這個一邊排序就可以了。

將長度累加到對應排名上面。樹狀數組維護查詢就可以了。


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 500010
ll s[N];
int n, m, q;

struct node {
    int u, c, l;
    bool operator<(const node&x ) const {
        return (u<x.u) || (u==x.u && c>x.c);
    }
} a[N];
inline int lowbit(int x) { return x & (-x); }
void add(int x, ll y) {
    while (x <= m) {
        s[x] += y;
        x += lowbit(x);
    }
}
ll sum(int x) {
    ll ret = 0;
    while (x) {
        ret += s[x];
        x -= lowbit(x);
    }
    return ret;
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    int T;
    scanf("%d", &T);
    for (int cas=1; cas<=T; cas++) {
        scanf("%d%d%d", &n, &m, &q);
        for (int i=0; i<m; i++)
            scanf("%d%d%d", &a[i].u, &a[i].c, &a[i].l);
        sort(a, a+m);
        memset(s, 0, sizeof(s));
        int last = 0;
        for (int i=0; i<m; i++) {
            if (a[i].u != a[last].u) last = i;
            add(i-last+1, (ll)a[i].l);
        }
        printf("Case #%d:\n", cas);
        int k;
        while (q--) {
            scanf("%d", &k);
            if (k > m) k = m;
            printf("%I64d\n", sum(k));
        }
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章