absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] BZOJ 3670
[破碎的状态] NFLJ OJ 1124 解题报告

[破碎的状态] BZOJ 2809

absi2011 posted @ Apr 20, 2016 03:36:43 PM in 刷题记录 with tags 小高考 bzoj 配对堆 , 576 阅读

重新学了一发配对堆

一篇不错的讲解:

http://wenku.baidu.com/link?url=N5FTv6Grq7pDfM20LdB4nk7nxvu6ALEtuh5WYxDPqPJjVBbk_rSw65yO3OIeMP5Mq6MMR1FbKLDn5SVkK77scP9lsFLyZFd-l7WZS0I_uOq

很多时候根本不需要left(last)指针,只需要child指针和right即可..

比如这题..我们需要一个join,link和delete_node就够了..

代码:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int father[100005],c[100005],l[100005];
struct node
{
    int y;
    node * ch;
    node * next;
};
node * root[100005];
node * new_node()
{
    static node a[100005];
    static int top=0;
    return &a[top++];
}
int size[100005];
node * join(node * x,node * y)
{
    if (x->y>y->y) swap(x,y);
    x->next=y->ch;
    y->ch=x;
    return y;
}
node * link(node * x)
{
    node * y=x->next;
    x->next=0;
    if (y==0) return x;
    node * z=y->next;
    if (z==0) return join(x,y);
    y->next=0;
    return join(link(z),join(x,y));
}
void delete_node(node * &x)
{
    x=link(x->ch);
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    for (i=0;i<n;i++)
    {
        scanf("%d%d%d",&father[i],&c[i],&l[i]);
        father[i]--;
    }
    for (i=0;i<n;i++)
    {
        root[i]=new_node();
        root[i]->ch=0;
        root[i]->next=0;
        root[i]->y=c[i];
        size[i]=1;
    }
    long long ans=0;
    for (i=n-1;i>=0;i--)
    {
        ans=max(ans,(long long)size[i]*l[i]);
        if (i!=0)
        {
            root[father[i]]=join(root[i],root[father[i]]);
            c[father[i]]+=c[i];
            size[father[i]]+=size[i];
            for (;c[father[i]]>m;)
            {
                size[father[i]]--;
                c[father[i]]-=root[father[i]]->y;
                delete_node(root[father[i]]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter