P1552 [APIO2012]派遣

以m的总价在线段树中找能雇佣的最大人数,然后向上合并

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include"vector"
  5 #define cint const int
  6 #define newnode() ++idx
  7 #include"iostream"
  8 using namespace std;
  9 int lch[3000010],rch[3000010];
 10 long long sum[3000010];
 11 int cnt[3000010];
 12 int idx;
 13 int root[100010];
 14 struct node{
 15     int a,b;
 16     inline bool operator<(const node &v)const{return a<v.a;}
 17 };
 18 node t[100010];
 19
 20 int n,m;
 21 int b[100010],c[100010];
 22 long long l[100010];
 23
 24 int rk[100010];
 25 long long ans;
 26
 27 void merge(int &u,cint &v,int l,int r){
 28
 29
 30     if((!u)||(!v)){
 31         sum[u+v]=sum[u]+sum[v];
 32         cnt[u+v]=cnt[u]+cnt[v];
 33         u=v+u;
 34     }
 35     else if (l==r)
 36     {
 37         sum[u]+=sum[v];
 38         cnt[u]+=cnt[v];
 39         return ;
 40     }
 41     else {
 42         int mid =l+r>>1;
 43          merge(lch[u],lch[v],l,mid);
 44         merge(rch[u],rch[v],mid+1,r);
 45         sum[u]=sum[lch[u]]+sum[rch[u]];
 46         cnt[u]=cnt[lch[u]]+cnt[rch[u]];
 47     }
 48 }
 49 void ins(cint &u,cint &left,cint &right,cint &pos,cint &w){
 50     sum[u]+=w;
 51     ++cnt[u];
 52     if (right==left)return ;
 53
 54             if(pos<=((left+right)>>1)){
 55             if(!lch[u])lch[u]=newnode();
 56             ins(lch[u],left,(left+right)>>1,pos,w);
 57         }else{
 58             if(!rch[u])rch[u]=newnode();
 59             ins(rch[u],(left+right)/2+1,right,pos,w);
 60         }
 61
 62
 63 }
 64
 65 vector<int > v;
 66
 67 int vv[600000];
 68 int bisearch(cint &u,cint &left,cint &right,cint &limit){
 69     if(!u)return 0;
 70     if(right>left)
 71     {
 72         if(sum[lch[u]]<=limit)
 73             return cnt[lch[u]]+bisearch(rch[u],(left+right)/2+1,right,limit-sum[lch[u]]);
 74         else
 75             return bisearch(lch[u],left,(left+right)>>1,limit);
 76     }
 77     else
 78     {
 79
 80         //if (right==n+1)return 0;
 81         return min(cnt[u],limit/(vv[right]));
 82         //if(sum[u]<=limit)return 1;
 83     //    return 0;
 84
 85     }
 86
 87
 88 }
 89
 90
 91
 92 int main(){
 93 /*     n=5; root[1]=++idx;
 94     ins(root[1],1,n,2,2) ;
 95    root[2]=++idx;
 96     ins(root[2],1,n,2,3);
 97     cout<<sum[root[2]];
 98     merge(root[2],root[1],1,n);
 99     cout<<sum[root[2]];
100
101     */
102     int i,j,k;
103     scanf("%d%d",&n,&m);
104     for(i=1;i<=n;++i){
105         scanf("%d%d%lld",b+i,c+i,l+i);
106         t[i]={c[i],i};
107        vv[i]=c[i];
108     }
109     stable_sort(t+1,t+n+1);
110
111     t[0].a=-1;int now = 0;
112
113
114
115   //  sort(v.begin(),v.end());
116    // v.erase(unique(v.begin(),v.end()),v.end());
117     sort(vv+1,vv+1+n); int tote;
118      tote=unique(vv+1,vv+1+n)-vv-1;;
119
120
121     for(i=1;i<=n;++i)
122     {
123
124         k=t[i].b;
125         rk[k]=lower_bound(vv+1,vv+1+tote,t[i].a)-vv;
126         //cout<<rk[k]<<endl;
127         root[k]=newnode();
128         ins(root[k],1,n,rk[k],c[k]);
129        // cout<<k<<" "<<sum[root[k]]<<" "<<cnt[root[k]]<<endl;
130
131     }
132   //  cout<<"***********"<<endl;
133     for(i=n;i;--i)
134     {
135     //    cout<<i<<" "<<sum[root[i]]<<" "<<bisearch(root[i],1,n,m)<<endl;
136         //    cout<<i<<endl;
137         ans=max(ans,l[i]*bisearch(root[i],1,n,m));
138       //  cout<<b[i]<<" "<<sum[root[b[i]]]<<endl;
139         if(b[i])merge(root[b[i]],root[i],1,n);
140        //  cout<<b[i]<<" "<<sum[root[b[i]]]<<endl;
141
142     }
143     printf("%lld\n",ans);
144 }

原文地址:https://www.cnblogs.com/zhangbuang/p/10349495.html

时间: 2024-10-05 17:49:29

P1552 [APIO2012]派遣的相关文章

[luogu P1552] [APIO2012]派遣

[luogu P1552] [APIO2012]派遣 题目背景 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. 题目描述 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送. 现在你要招募一批忍者,并把它们派遣给顾客.你需要为每个被派遣的忍者支付一定的薪水,同时使得支付的薪水总额不超过你的预算.另外,为了发送指

Luogu P1552 [APIO2012]派遣 主席树

题目链接 Click Here 这个题好像大多数人用的都是左偏树啊?这里我来贡献一发主席树的解法. 把题目中的问题抽象出来,其实就是询问每一个点的子树中,工资前\(tot_i\)大的点,使它们的和满足\(\sum cost_i<=m\),在此前提下使\(tot_i\)尽可能大,答案就是\(ans=max(tot_i*lead_i)\). 如果只有一个点的话直接二分一下就好了,但现在树上的每一个点都可能是答案的产生1处.为了便于访问每一棵子树,我们把原先的树按\(dfs\)序划分,子树显然就是连续

[APIO2012]派遣

P1552 [APIO2012]派遣https://www.luogu.org/problemnew/show/P1552 题目背景 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. 题目描述 在这个帮派里,有一名忍者被称之为\(Master\).除了\(Master\)以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送. 现在你要招募一批忍者,并把它们派遣给顾客.你需要为

[APIO2012]派遣 解题报告

796. [APIO2012] 派遣 [问题描述] 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接下属,而不允许通过其他的方式发送. 现在你要招募一批忍者,并把它们派遣给顾客.你需要为每个被派遣的忍者支付一定的薪水,同时使得支付的薪水总额不超过你的预算.另外,为了发送指令,你需要选择一名忍者

APIO2012派遣

2809: [Apio2012]dispatching Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1196  Solved: 586[Submit][Status] Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的领导力,所有与他们工作相关的指令总是由上级发送给他的直接

「Luogu1552」[APIO2012]派遣

「Luogu1552」[APIO2012]派遣 最近状态都不是很好,写完这个题感觉手感好像恢复了一些 problem Solution 这个数据范围显然树形DP是做不了的 我们考虑,在预算范围内,选中的忍者越多越好,那么我们在一棵子树中选中的忍者一定是薪水最少的若干个 对每个节点维护一个大根堆,并记录每个堆的大小和堆中元素的权值和 考虑一棵子树时,用类似树形DP的方法将所有儿子合并到根 如果堆中元素权值和大于预算,不断弹出堆顶直到权值和不大于预算即可 最后对子树进行统计,更新答案 可并堆可以用左

[Luogu1552][APIO2012]派遣--(左偏树)

首先,洛谷传送门 题目大意: 有一颗n个节点的树,每个节点都有li(领导值),fi(父亲),ci(cost)三个值,要求选定一个节点x,并在其与其子树中选出任意数量的点,使所有选的点的总花费x不超过m,使权值(所选点的个数*lx)最大. 解题思路: 其实这题只要看懂题了还是很好做的,首先很好想到树形DP,对于每个节点,可以选出在其子树中最小的几个节点使其花费刚好不超过m,在乘上自己的l值,但每次去取最小花费的节点时间复杂度过于复杂,因此,可以想到用可并堆来维护每个节点的儿子,再向父亲转移即可,因

APIO2012 派遣dispatching | 左偏树版本&amp;&amp;pb_ds版本

题目链接:戳我 就是尽可能地选取排名小的,加起来就可以了.然后我们考虑利用一个大根堆,一个一个合并,如果超过派遣的钱,我们就把费用最大的那个忍者丢出队列. 左偏树,作为一个十分优秀的可并堆,我们这道题利用的就是这个数据结构. 左偏树不会?戳我 这里有一张来自HolseLee dalao的图: 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #def

浅谈左偏树在OI中的应用

Preface 可并堆,一个听起来很NB的数据结构,实际上比一般的堆就多了一个合并的操作. 考虑一般的堆合并时,当我们合并时只能暴力把一个堆里的元素一个一个插入另一个堆里,这样复杂度将达到\(\log(|A|)+\log(|B|)\),极限数据下显然是要T爆的. 所以我们考虑使用一种性价比最高的可并堆--左偏树,它的思想以及代码都挺简单而且效率也不错. 学习和参考自这里 What is Leftist Tree 左偏树,顾名思义就是像左偏的树,但是这样抽象的表述肯定是不符合我们学OI的人的背板子