zoukankan      html  css  js  c++  java
  • BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆

    https://www.lydsy.com/JudgeOnline/problem.php?id=4003

    感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始终保持右边堆的深度比左边堆的小一些以保证复杂度,大概因为这个所以也叫左偏树吧。

    这个题我最开始看错题目了所以看板子的时候一头雾水满脑子都是“这个实现有问题吧”,然后又看了一遍题目发现没问题骑士就是往上走的。

    这道题是把每个点建一个堆然后从叶子到根向上传递+去掉没法再往上的,复杂度大概是O(nlogn)?

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int maxn=300010;
     9 long long read(){
    10     long long x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while('0'<=ch&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }
    13     return x*f;
    14 }
    15 int n,m;
    16 long long h[maxn]={},k[maxn]={},b[maxn]={},s[maxn]={};
    17 int fa[maxn]={},c[maxn]={};
    18 int rt[maxn]={},ans1[maxn]={},ans2[maxn]={};
    19 struct use{ int y,next; }e[maxn];
    20 int head[maxn]={},dep[maxn]={},tot=0;
    21 struct hp{ long long k,b,v; int dis,l,r; }t[maxn];
    22 void init(int x,int y){
    23     e[++tot].y=y;e[tot].next=head[x];head[x]=tot;
    24 }
    25 inline void Ad(int x,long long tk,long long tb){
    26     t[x].k*=tk;
    27     t[x].b=t[x].b*tk+tb;
    28     t[x].v=t[x].v*tk+tb;
    29 }
    30 inline void downdata(int x){
    31     if(t[x].l)Ad(t[x].l,t[x].k,t[x].b);;
    32     if(t[x].r)Ad(t[x].r,t[x].k,t[x].b);
    33     t[x].k=1;t[x].b=0;
    34 }
    35 int merge(int x,int y){
    36     if(!x)return y;if(!y)return x;
    37     downdata(x);downdata(y);
    38     if(t[x].v>t[y].v)swap(x,y);
    39     t[x].r=merge(t[x].r,y);
    40     if(t[t[x].r].dis>t[t[x].l].dis)swap(t[x].r,t[x].l);
    41     t[x].dis=t[t[x].r].dis+1;
    42     return x;
    43 }
    44 void dfs(int x){
    45     int y;
    46     for(int i=head[x];i;i=e[i].next){
    47         y=e[i].y;
    48         dep[y]=dep[x]+1;
    49         dfs(y);Ad(rt[y],k[y],b[y]);
    50         rt[x]=merge(rt[x],rt[y]);
    51     }
    52     while(rt[x]&&t[rt[x]].v<h[x]){
    53         downdata(rt[x]);ans1[x]++;
    54         ans2[rt[x]]=dep[c[rt[x]]]-dep[x];
    55         rt[x]=merge(t[rt[x]].l,t[rt[x]].r);
    56     }
    57 }
    58 int main(){
    59     n=read();m=read();
    60     for(int i=1;i<=n;i++)h[i]=read();
    61     for(int i=2;i<=n;i++){
    62         fa[i]=read();init(fa[i],i);
    63         k[i]=read();b[i]=read();
    64         if(!k[i])k[i]=1;
    65         else{k[i]=b[i];b[i]=0;}
    66     }
    67     for(int i=1;i<=m;i++){
    68         s[i]=read();c[i]=read();
    69         t[i].k=1; t[i].b=0; t[i].v=s[i];
    70         rt[c[i]]=merge(rt[c[i]],i);
    71     }dep[1]=1;
    72     dfs(1);
    73     while(rt[1]){
    74         downdata(rt[1]);
    75         ans2[rt[1]]=dep[c[rt[1]]];
    76         rt[1]=merge(t[rt[1]].l,t[rt[1]].r);
    77     }
    78     for(int i=1;i<=n;i++)printf("%d
    ",ans1[i]);
    79     for(int i=1;i<=m;i++)printf("%d
    ",ans2[i]);
    80     return 0;
    81 }
    View Code

  • 相关阅读:
    年近30,朋友聚会都聊什么?
    2016世界最热门的编程语言与薪资揭秘
    程序员的春天来了,最美赏花旅游地十大攻略
    雄联盟工程师独家分享:如何使开发更有效率
    小偷被抓叫嚣:我不偷警察没饭吃
    3.7女生节:被程序员男友送的奇葩礼物宠哭了
    最适合程序员加班吃的6大营养美食
    谷歌汽车出误判曝光 6大奇葩科技更牛
    【程序员的爱情】彼岸花开谁又种下了执念
    分享10个免费或便宜的Photoshop替代工具
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8664192.html
Copyright © 2011-2022 走看看