zoukankan      html  css  js  c++  java
  • BZOJ2809: [Apio2012]dispatching

    给n<=100000的树,每个点有权值和代价,有m<=1e9的容量,问:一个点权值*子树内代价总和不超过容量的最大点数的最大值。

    其实就是要合并。平衡树、线段树、可并堆挑一个。

    可并堆由于没法二分,故“正难取反”,维护最大的,在不够装时弹掉。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 //#include<assert.h>
     6 #include<algorithm>
     7 //#include<iostream>
     8 using namespace std;
     9 
    10 int n,m;
    11 #define maxn 100011
    12 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
    13 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
    14 void insert(int x,int y) {in(x,y); in(y,x);}
    15 
    16 #define LL long long
    17 struct leftist
    18 {
    19     struct Node
    20     {
    21         int size,ls,rs,dis,v; LL sum;
    22     }a[maxn];
    23     leftist() {a[0].dis=-1;}
    24     int merge(int x,int y)
    25     {
    26         if (!x || !y) return x^y;
    27         if (a[x].v<a[y].v) {int t=x; x=y; y=t;}
    28         a[x].rs=merge(a[x].rs,y);
    29         if (a[a[x].ls].dis<a[a[x].rs].dis) {int t=a[x].ls; a[x].ls=a[x].rs; a[x].rs=t;}
    30         a[x].dis=a[a[x].rs].dis+1;
    31         a[x].size=a[a[x].ls].size+a[a[x].rs].size+1;
    32         a[x].sum=a[a[x].ls].sum+a[a[x].rs].sum+a[x].v;
    33         return x;
    34     }
    35     void push(int id,int &root,int val)
    36     {
    37         a[id].v=val; a[id].size=1; a[id].sum=val;
    38         a[id].ls=a[id].rs=a[id].dis=0;
    39         root=merge(root,id);
    40     }
    41     void pop(int &root) {root=merge(a[root].ls,a[root].rs);}
    42     int top(int root) {return a[root].v;}
    43 }q;
    44 int root[maxn];
    45 int find(int x) {return x==root[x]?x:(root[x]=find(root[x]));}
    46 
    47 int b[maxn]; LL ans=-1e18;
    48 void dfs(int x)
    49 {
    50     for (int i=first[x];i;i=edge[i].next)
    51     {
    52         const Edge &e=edge[i];
    53         dfs(e.to);
    54         root[x]=q.merge(root[x],root[e.to]);
    55     }
    56     while (q.a[root[x]].sum>m) q.pop(root[x]);
    57     ans=max(ans,q.a[root[x]].size*1ll*b[x]);
    58 }
    59 
    60 int main()
    61 {
    62     scanf("%d%d",&n,&m);
    63     int rr=0;
    64     for (int i=1,x,y;i<=n;i++)
    65     {
    66         scanf("%d%d%d",&x,&y,&b[i]);
    67         if (x==0) rr=i; else in(x,i);
    68         q.push(i,root[i],y);
    69     }
    70     dfs(rr);
    71     printf("%lld
    ",ans);
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    中介模式与外观模式(门面模式)区别
    java反射
    Spring注解@ResponseBody,@RequestBody
    Spring事务管理
    Junit运行在Spring环境下
    java开发常用到的jar包总结
    java二维数组
    Android开发之执行定时任务AlarmManager,Timer,Thread
    Android开发之Android Context,上下文(Activity Context, Application Context)
    Android开发之创建App Widget和更新Widget内容
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8266974.html
Copyright © 2011-2022 走看看