zoukankan      html  css  js  c++  java
  • 【BZOJ】【2809】【APIO2012】派遣dispatching

    贪心/可并堆


      跪了……我这么弱果然还是应该回家种红薯去……

      考虑选人的时候,每个人对答案的贡献其实是一样的,都是1,那么我们就贪心地去选花钱少的就好啦~

      具体的做法:倒着枚举(因为有b[i]<i),考虑选第 i 个人做领导者的时候,以他为根的子树中如果花费>m,那么我们就踢掉花钱最多的人,直到sum<m,用l[i]*num[i]更新答案(num[i]表示以 i 为根的子树中选了多少人),然后把这棵子树的堆并到他的父亲的堆中去(初始每个人的堆都只有他自己)

      或许你看看代码更容易理解一点……

      总之就是枚举领导者,属下能多选就多选,不能选的时候踢掉花钱最多的那个

      当然这题只要是支持快速合并以及删除最大值的数据结构都可以的……比如用splay/treap+启发式合并也可以捉,嗯我写的是左偏树……

     1 /**************************************************************
     2     Problem: 2809
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:948 ms
     7     Memory:7528 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2809
    11 #include<vector>
    12 #include<cstdio>
    13 #include<cstring>
    14 #include<cstdlib>
    15 #include<iostream>
    16 #include<algorithm>
    17 #define rep(i,n) for(int i=0;i<n;++i)
    18 #define F(i,j,n) for(int i=j;i<=n;++i)
    19 #define D(i,j,n) for(int i=j;i>=n;--i)
    20 #define pb push_back
    21 using namespace std;
    22 inline int getint(){
    23     int v=0,sign=1; char ch=getchar();
    24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    26     return v*sign;
    27 }
    28 const int N=100010,INF=~0u>>2;
    29 typedef long long LL;
    30 /******************tamplate*********************/
    31 LL n,m,b[N],c[N],l[N],rt[N];
    32 LL ans=0;
    33 struct node{
    34     int v,l,r,dis,f,num; LL sum;
    35     node(int v=0,int l=0,int r=0,int dis=0,
    36          int f=0,int num=0,LL sum=0):
    37         v(v),l(l),r(r),dis(dis),
    38         f(f),num(num),sum(sum){}
    39 };
    40 struct Left_tree{
    41     node t[N];
    42     int merge(int x,int y){
    43         if(!x||!y) return x?x:y;
    44         if (t[x].v<t[y].v) swap(x,y);
    45         t[x].r=merge(t[x].r,y);
    46 //      t[t[x].r].f=x;
    47         if (t[t[x].l].dis<t[t[x].r].dis) swap(t[x].l,t[x].r);
    48         if (t[x].r==0) t[x].dis=0;
    49         else t[x].dis=t[t[x].r].dis+1;
    50         t[x].sum=t[t[x].l].sum+t[t[x].r].sum+t[x].v;
    51         t[x].num=t[t[x].l].num+t[t[x].r].num+1;
    52         return x;
    53     }
    54     int pop(int x){
    55         int l=t[x].l,r=t[x].r;
    56 //      t[l].f=l; t[r].f=r;
    57         t[x].l=t[x].r=t[x].dis=0;
    58         return merge(l,r);
    59     }
    60     void init(){
    61         n=getint();m=getint();
    62         F(i,1,n){
    63             b[i]=getint();
    64             t[i].sum=t[i].v=getint();
    65             l[i]=getint();
    66  
    67             t[i].num=1;
    68             rt[i]=i;
    69         }
    70         D(i,n,1){
    71             while(t[rt[i]].sum>m) rt[i]=pop(rt[i]);
    72             if (t[rt[i]].num*l[i]>ans) ans=t[rt[i]].num*l[i];
    73             if (rt[i] && b[i]) rt[b[i]]=merge(rt[b[i]],rt[i]);
    74         }
    75         printf("%lld
    ",ans);
    76     }
    77 }H;
    78 int main(){
    79 #ifndef ONLINE_JUDGE
    80     freopen("2809.in","r",stdin);
    81     freopen("2809.out","w",stdout);
    82 #endif
    83     H.init();
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    .net Application的目录
    (转载).NET中RabbitMQ的使用
    (转载)RabbitMQ消息队列应用
    说说JSON和JSONP
    SQL Server中的事务与锁
    StackExchange.Redis Client(转载)
    正则语法的查询,这是纯转载的,为了方便查询
    Regex的性能问题
    解决json日期格式问题的办法
    BenchmarkDotNet(性能测试)
  • 原文地址:https://www.cnblogs.com/Tunix/p/4371496.html
Copyright © 2011-2022 走看看