昨天看了可并堆是什么,写的是左偏树

大概就是一棵树

1、有左偏性质,即当前根到左叶子节点距离比到右叶子节点距离大

2、有堆性质,堆顶关键字比子树关键字小

合并两个堆的时候,关键字大的插入到关键字小的那堆的右子树中,右子树的深度大于左子树时交换两者以维持左偏性质。

堆中个数太多的时候,pop堆顶的元素x

具体是合并左右两个子树后返回新的堆顶元素y,清除完x的信息后root[x]指向y

bzoj1455:用并查集合并团,用可并堆维护团中最小的人。

 #include<stdio.h>
 #include<string.h>
 #include<algorithm>
 using namespace std;
 ;
 int n,m,v[maxn],vis[maxn],fa[maxn],l[maxn],r[maxn],a,b,d[maxn];
 ];

 int find(int x){
     return (fa[x]==x)?x:fa[x]=find(fa[x]);
 }

 int merge(int x, int y){
     if (!x || !y) return x+y;
     if (v[x]>v[y]) swap(x,y);  //保证堆顶最小
     r[x]=merge(r[x],y);
     if (d[r[x]]>d[l[x]]) swap(l[x],r[x]);
     d[x]=d[r[x]]+;
     return x;
 }

 int main(){
     scanf("%d", &n);
     ; i<=n; i++) scanf("%d", &v[i]);
     scanf(]=-;
     ; i<=n; i++) fa[i]=i;
     ; i<=m; i++){
         scanf("%s", s);
         ]=='M'){
             scanf("%d%d", &a, &b);
             if (vis[a] || vis[b]) continue;
             int fx=find(a), fy=find(b);
             if (fx!=fy) fa[fx]=fa[fy]=merge(fx,fy); // 合并从堆顶开始合并
         }else{
             scanf("%d", &a);
             ");
             else{
                 ;// printf("  %d\n", fx);
                 printf("%d\n", v[fx]);
                 fa[fx]=merge(l[fx],r[fx]);
                 fa[fa[fx]]=fa[fx];
             }
         }
     }
     ;
 }

bzoj2809:DFS一遍,从叶子节点开始向上递归,到一个节点,可并堆维护当前子树中满足预算的最多人数,然后用当前子树更新答案。具体是每个节点都插入,超出预算就pop最大花费的人直到满足预算

 #include<stdio.h>
 #include<string.h>
 #include<algorithm>
 #define LL long long
 using namespace std;
 ;
 struct node{
     int to,next;
 }e[maxn];
 struct heap{
     int l,r;
     LL val;
 }t[maxn];
 ,head[maxn];
 LL v[maxn],w[maxn],ans,sum[maxn],add[maxn];

 void insert(int u, int v){
     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
 }

 int merge(int x, int y){
     if (!x || !y) return x+y;
     if (t[x].val<t[y].val) swap(x,y);
     t[x].l=merge(t[x].l,y);
     swap(t[x].l,t[x].r);
     return x;
 }

 void Pop(int x){
     int rt=root[x];
     root[x]=merge(t[rt].l,t[rt].r);
     sum[x]--; add[x]-=t[rt].val;
     t[rt].l=t[rt].r=t[rt].val=;
 }

 void dfs(int u){
     add[u]=sum[u]=;
     for (int i=head[u],vv; i; i=e[i].next){
         dfs(vv=e[i].to);
         add[u]+=add[vv]; sum[u]+=sum[vv];
         root[u]=merge(root[u],root[vv]);
         while (add[u]>m) Pop(u);
     }
     add[u]+=v[u]; sum[u]++;
     t[u]=(heap){,,v[u]};
     root[u]=merge(root[u],u);
     while (add[u]>m) Pop(u);
     ans=max(ans,sum[u]*w[u]);
 }

 int main(){
     scanf("%d%d", &n, &m); int s;
     ; i<=n; i++){
         int x;
         scanf("%d%lld%lld", &x, &v[i], &w[i]);
         insert(x,i); if (!x) s=i;
     }
     dfs(s);
     printf("%lld\n", ans);
     ;
 }

bzoj1455: 罗马游戏 + bzoj2809: Dispatching(可并堆)的更多相关文章

  1. [bzoj1455]罗马游戏_左偏树_并查集

    罗马游戏 bzoj-1455 题目大意:给你n个人,2种操作,m次操作:1.将i号士兵所在的集合的最小值删除 2.合并i和j两个士兵所在的团体 注释:$1\le n\le 10^6$,$1\le m ...

  2. [BZOJ1455]罗马游戏 左偏树+并查集

    1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 2285  Solved: 994[Submit][Status][Discuss] ...

  3. BZOJ1455 罗马游戏 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1455 题意概括 n个人,2种操作. 一种是合并两个人团,一种是杀死某一个人团的最弱的人. 题解 左 ...

  4. Bzoj1455 罗马游戏

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1622  Solved: 679 Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人 ...

  5. 【数据结构】bzoj1455罗马游戏

    Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻 ...

  6. BZOJ1455——罗马游戏

    1.题目大意:维护一个数据结构,可以实现合并操作,还能询问最小值 2.分析:这种问题当然是可并堆啦 随便写了一个左偏树QAQ #include <cstdio> #include < ...

  7. [BZOJ1455]罗马游戏(左偏树)

    用并查集和左偏树维护士兵的关系 Code #include <cstdio> #include <algorithm> #define N 1000010 using name ...

  8. BZOJ1455罗马游戏

    左偏树裸题. 题面描述让人意识到了平面几何的重要性. //Achen #include<algorithm> #include<iostream> #include<cs ...

  9. 【BZOJ-1455】罗马游戏 可并堆 (左偏树)

    1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1355  Solved: 561[Submit][Status][Discuss] ...

随机推荐

  1. tp5 model 的时间戳

    单独在模型里面设置:(推荐) protected $autoWriteTimestamp = true; // int 型 protected $autoWriteTimestamp = 'datet ...

  2. DataSet装换为泛型集合 222

    #region DataSet装换为泛型集合 /// <summary> /// 利用反射和泛型 /// </summary> /// <param name=" ...

  3. Linux /proc/$pid部分内容详解

    auxv /proc/[pid]/auxv包含传递给进程的ELF解释器信息,格式是每一项都是一个unsigned long长度的ID加上一个unsigned long长度的值.最后一项以连续的两个0x ...

  4. python之模块

    模块即一推代码的集合来实现某个功能,使用时直接调用,甚是方便. 模块又分为三种 自定义模块 内置模块 第三方模块 下面就来介绍介绍什么是内置模块及如何去使用它和内置模块的好处. 使用模块模块前首先导入 ...

  5. DataTable 只保留想要的几列

    using System; using System.Collections; using System.Configuration; using System.Data; using System. ...

  6. Problem with "AnyConnect was not able to establish connection to the specified secure gateway."

    Cisco的VPN客户端最近报"AnyConnect was not able to establish connection to the specified secure gateway ...

  7. mac个人设置

    修改spotlight快捷键 mac默认的command+space和我windows下的习惯冲突,修改为ctrl+space 删除输入法切换的快捷键 因为我不需要切换不同语言的快捷键.中英文切换直接 ...

  8. Linux内核--内核数据类型

    转自:http://www.linuxidc.com/Linux/2013-12/93637.htm 将Linux 移植到新的体系结构时,开发者遇到的若干问题都与不正确的数据类型有关.坚持使用严格的数 ...

  9. SQL2005 表分区亲测

    --增加文件组 alter database Test add filegroup [FG1] go alter database Test add filegroup [FG2] GO alter ...

  10. 【Mybatis架构】 延迟加载

    在上一篇博客中,我们提到过有关于Mybatis输出映射中resultMap能够实现延迟加载的事,然而真的是所有的resultMap都能实现延迟加载还是咋地啊?现在我们就来对那一句话做一下阐述和实例说明 ...