hdu4020

Ads Proposal

网上有用树状数组做的,但我对树状数组非常不熟……所以只能用比较暴力的做法,set+前缀和OTZ(其实也写了一个树状数组的,只不过基本就是在抄题解hhhhhhh)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <cctype>
#include <string>
#include <queue>
#define debug printf("debugn")
#define mst(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
const int maxn=1e5+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
struct {
ll cli;
ll len;
bool operator<(const ad& a) const{
return cli>a.cli;
}
};
ll sum[maxn*5];
set<ad> cus[maxn];
int main()
{
int t;
scanf("%d",&t);
int kase=0;
while(t--)
{
int n,m,q;
scanf("%d %d %d",&n,&m,&q);
for(int i=0;i<=n;i++)
cus[i].clear();
for(int i=0;i<m;i++){
ad tmp;int u;
scanf("%d %lld %lld",&u,&tmp.cli,&tmp.len);
cus[u].insert(tmp);
}
mst(sum,0);
set<ad>::iterator it;
for(int i=1;i<=n;i++){
int idx=1;
for(it=cus[i].begin();it!=cus[i].end();it++){
sum[idx++]+=(*it).len;
}
}
for(int i=1;i<=m;i++)
sum[i]=sum[i]+sum[i-1];
printf("Case #%d:n",++kase);
for(int i=0;i<q;i++){
int k;
scanf("%d",&k);
k=min(k,m);
printf("%lldn",sum[k]);
}
}
return 0;
}

比较有意思的是计算前缀和的部分,这里解释一下。其实就是对于每一个customer,把他每一个广告的长度加到对应的第i个广告长度和上,然后将这个过程循环起来。最后再在这个基础上求个前缀和即可