BZOJ2809 dispatching

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2809

知识点:  可持久化线段树、DFS序

解题思路:

  先根据给出的树处理出每一点的\(DFS\)序,记录每一棵子树的最小(\(Le\))、最大(\(Ri\)) \(DFS\)序。先建一棵空的权值线段树(从小到大),然后根据\(DFS\)序可持久化更新线段树。查询答案的时候枚举每一个点,查询以这一点为根的子树对应的第\(Le\)个和第\(Ri\)版本之间的线段树,尽量多取点,取到\(M\)预算不够为止,答案就是取的点数乘根点对应的领导力的最大值。

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 100000+5;
 5 
 6 int fa[maxn];
 7 vector<int> G[maxn];
 8 struct poi{
 9     int id;
10     ll cost;
11 }per[maxn];
12 bool cmp(const poi &a,const poi &b){
13     return a.cost<b.cost;
14 }
15 int pos[maxn];
16 ll lin[maxn];
17 
18 int tot=0;
19 int T[maxn*30],lson[maxn*30],rson[maxn*30];
20 int siz[maxn*30];
21 ll sum[maxn*30];
22 
23 int dfsxu[maxn],redfsxu[maxn];
24 int le[maxn],ri[maxn];
25 int temp=0;
26 void build(int l, int r, int &rt) {
27     rt = ++tot;
28     sum[rt] = 0LL;
29     siz[rt] = 0;
30     if (l == r)    return;
31     int m = (l + r) >> 1;
32     build(l, m, lson[rt]);    build(m + 1, r, rson[rt]);
33 }
34 void update(int last, int pos, int l, int r, int &rt) {
35     rt = ++tot;
36     lson[rt] = lson[last];
37     rson[rt] = rson[last];
38     siz[rt] = siz[last] + 1;
39     sum[rt] = sum[last] + per[pos].cost;
40     if (l == r)    return;
41     int m = (l + r) >> 1;
42     if (pos <= m)    update(lson[last], pos, l, m, lson[rt]);
43     else            update(rson[last], pos, m + 1, r, rson[rt]);
44 }
45 int query(int s, int t, ll maxc, int l, int r) {
46     if (l == r){
47         if(sum[t]-sum[s]<=maxc)
48             return siz[t]-siz[s];
49         return 0;
50     }
51     int m = (l + r) >> 1;
52     ll tmp = sum[lson[t]] - sum[lson[s]];
53     int ret;
54     if (maxc <= tmp)    ret = query(lson[s], lson[t], maxc, l, m);
55     else            ret = siz[lson[t]]-siz[lson[s]]+query(rson[s], rson[t], maxc - tmp, m + 1, r);
56     return ret;
57 }
58 void dfs(int rt){
59     redfsxu[rt]=temp;
60     dfsxu[temp]=rt,le[rt]=temp;
61     temp++;
62     for(int i=0;i<G[rt].size();i++)
63         dfs(G[rt][i]);
64     ri[rt]=temp-1;
65 }
66 
67 int main(){
68     int N;
69     ll M;
70     scanf("%d%lld",&N,&M);
71     for(int i=1;i<=N;i++){
72         scanf("%d%lld%lld",&fa[i],&per[i].cost,&lin[i]);
73         per[i].id=i;
74         G[fa[i]].push_back(i);
75     }
76     sort(per+1,per+1+N,cmp);
77     for(int i=1;i<=N;i++)
78         pos[per[i].id]=i;
79     dfs(0);
80     build(1,N,T[0]);
81 
82     for(int i=1;i<=N;i++){
83         int now=dfsxu[i];
84         update(T[i-1],pos[now],1,N,T[i]);
85     }
86     ll ans=0;
87     for(int i=1;i<=N;i++){
88         int ret=query(T[le[i]-1],T[ri[i]],M,1,N);
89         ans=max(ans,lin[i]*(ll)ret);
90     }
91     printf("%lld\n",ans);
92 
93     return 0;
94 }

 

posted @ 2018-02-05 23:42  Blogggggg  阅读(150)  评论(0编辑  收藏  举报