zoukankan      html  css  js  c++  java
  • 洛谷P3261 [JLOI2015]城池攻占(左偏树)

    传送门

    每一个城市代表的点开一个小根堆,把每一个骑士合并到它开始攻占的城池所代表的点上

    然后开始dfs,每一次把子树里那些还活着的骑士合并上来

    然后再考虑当前点的堆,一直pop直到骑士全死光或者剩下的骑士的攻击力都大于等于当前城池的生命值,同时维护城池和骑士的答案

    然后修改的话在堆顶打一个标记,需要的时候下传即可

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define ll long long
     4 using namespace std;
     5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     6 char buf[1<<21],*p1=buf,*p2=buf;
     7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
     8 inline ll read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;ll res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 char sr[1<<21],z[20];int K=-1,Z;
    19 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
    20 inline void print(int x){
    21     if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x;
    22     while(z[++Z]=x%10+48,x/=10);
    23     while(sr[++K]=z[Z],--Z);sr[++K]='
    ';
    24 }
    25 const int N=3e5+5;
    26 int head[N],Next[N],ver[N],tot;
    27 inline void add_edge(int u,int v){
    28     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    29 }
    30 int L[N],R[N],rt[N],d[N],ans1[N],ans2[N],dep[N],c[N],n,m;
    31 ll add[N],mul[N],v[N],h[N],val[N];bool fl[N];
    32 inline void ppd(int p,ll m,ll a){
    33     if(p){
    34         v[p]*=m,v[p]+=a;
    35         mul[p]*=m,add[p]*=m,add[p]+=a;
    36     }
    37 }
    38 inline void pd(int p){
    39     ppd(L[p],mul[p],add[p]),ppd(R[p],mul[p],add[p]);
    40     mul[p]=1,add[p]=0;
    41 }
    42 int merge(int x,int y){
    43     if(!x||!y) return x+y;
    44     pd(x),pd(y);
    45     if(v[x]>v[y]) swap(x,y);
    46     R[x]=merge(R[x],y);
    47     if(d[L[x]]<d[R[x]]) swap(L[x],R[x]);
    48     d[x]=d[R[x]]+1;return x;
    49 }
    50 void dfs(int u,int fa){
    51     dep[u]=dep[fa]+1;
    52     for(int i=head[u];i;i=Next[i]){int v=ver[i];dfs(v,u),rt[u]=merge(rt[u],rt[v]);}
    53     while(rt[u]&&v[rt[u]]<h[u]){
    54         pd(rt[u]);++ans1[u],ans2[rt[u]]=dep[c[rt[u]]]-dep[u];
    55         rt[u]=merge(L[rt[u]],R[rt[u]]);
    56     }
    57     fl[u]?ppd(rt[u],val[u],0):ppd(rt[u],1,val[u]);
    58 }
    59 int main(){
    60 //    freopen("testdata.in","r",stdin);
    61     n=read(),m=read();
    62     for(int i=1;i<=n;++i) h[i]=read();
    63     for(int i=2;i<=n;++i){
    64         int fa=read();fl[i]=read(),val[i]=read();
    65         add_edge(fa,i);
    66     }
    67     for(int i=1;i<=m;++i){
    68         v[i]=read(),c[i]=read();
    69         mul[i]=1;
    70         rt[c[i]]=merge(rt[c[i]],i);
    71     }
    72     dfs(1,0);
    73     while(rt[1]) pd(rt[1]),ans2[rt[1]]=dep[c[rt[1]]],rt[1]=merge(L[rt[1]],R[rt[1]]);
    74     for(int i=1;i<=n;++i) print(ans1[i]);
    75     for(int i=1;i<=m;++i) print(ans2[i]);
    76     Ot();
    77     return 0;
    78 }
  • 相关阅读:
    使用Ansible安装部署nginx+php+mysql之安装php(2)
    使用Ansible安装部署nginx+php+mysql之安装nginx(1)
    Ansible常见问题处理
    4.2、Ansible常用模块
    3.2、Ansible单命令测试
    2、Ansible配置文件详解
    4.1、Ansible模块
    3.3、Ansible命令参数详解
    3.1、Ansible命令简要说明及初步使用
    1、Ansible初识简要介绍及安装
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9806327.html
Copyright © 2011-2022 走看看