JLOI2015 城池攻占

额...左偏树(可并堆)。

两件事情,1:需要用到lazy标记(左偏树是二叉数据结构,可以PushDown)2.用到lazy标记时,注意先乘后加(在打标记的时候修改加法标记)

剩下的,就是dfs模拟(有一些奇怪的OJ会发生爆栈的鬼畜事情)

维护小根堆,以能到达这个节点的骑士的战斗力为排序基准

之后每次删除不能满足的节点,剩下的就是类板子了,可以放心食用

递归版

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <queue>
  7 #include <iostream>
  8 using namespace std;
  9 #define N 300005
 10 #define ll long long
 11 struct node
 12 {
 13     int ls,rs,dis;ll x,add,mul;
 14 }mp[N<<1];
 15 struct no
 16 {
 17     int to,next;
 18 }e[N];
 19 ll h[N],v[N];
 20 int head[N],cnt,fa[N],dep[N],a[N],siz[N],ans[N],s[N],n,m;
 21 void add(int x,int y)
 22 {
 23     e[cnt].to=y;
 24     e[cnt].next=head[x];
 25     head[x]=cnt++;
 26     return ;
 27 }
 28 void PushDown(int x)
 29 {
 30     if(mp[x].mul!=1)
 31     {
 32         mp[mp[x].ls].x*=mp[x].mul;
 33         mp[mp[x].rs].x*=mp[x].mul;
 34         mp[mp[x].ls].mul*=mp[x].mul;
 35         mp[mp[x].rs].mul*=mp[x].mul;
 36         mp[mp[x].ls].add*=mp[x].mul;
 37         mp[mp[x].rs].add*=mp[x].mul;
 38         mp[x].mul=1;
 39     }
 40     if(mp[x].add)
 41     {
 42         if(mp[x].ls)
 43             mp[mp[x].ls].x+=mp[x].add,mp[mp[x].ls].add+=mp[x].add;
 44         if(mp[x].rs)
 45             mp[mp[x].rs].x+=mp[x].add,mp[mp[x].rs].add+=mp[x].add;
 46         mp[x].add=0;
 47     }
 48 }
 49 int merge(int x,int y)
 50 {
 51     if(!x)return y;
 52     if(!y)return x;
 53     if(mp[x].x>mp[y].x)swap(x,y);
 54     PushDown(x);
 55     mp[x].rs=merge(mp[x].rs,y);
 56     if(mp[mp[x].rs].dis>mp[mp[x].ls].dis)swap(mp[x].ls,mp[x].rs);
 57     mp[x].dis=mp[mp[x].rs].dis+1;
 58     return x;
 59 }
 60 void dfs(int x,int from)
 61 {
 62     for(int i=head[x];i!=-1;i=e[i].next)
 63     {
 64         int to1=e[i].to;
 65         dep[to1]=dep[x]+1;
 66         dfs(to1,x);
 67         int fx=fa[x],fy=fa[to1];
 68         fa[x]=merge(fx,fy);
 69     }
 70     if(!fa[x])return ;
 71     int fx=fa[x];
 72     while(mp[fx].x<h[x])
 73     {
 74         PushDown(fx);
 75         fa[x]=merge(mp[fx].ls,mp[fx].rs);
 76         siz[x]++;
 77         ans[fx]=dep[s[fx]]-dep[x];
 78         if(!fa[x])return;
 79         fx=fa[x];
 80     }
 81     if(a[x])
 82     {
 83         mp[fx].x*=v[x];
 84         mp[fx].mul*=v[x];
 85         mp[fx].add*=v[x];
 86     }else
 87     {
 88         mp[fx].x+=v[x];
 89         mp[fx].add+=v[x];
 90     }
 91     return ;
 92 }
 93 int main()
 94 {
 95     memset(head,-1,sizeof(head));
 96     memset(ans,-1,sizeof(ans));
 97     scanf("%d%d",&n,&m);
 98     for(int i=1;i<=n;i++)scanf("%lld",&h[i]);
 99     for(int i=2;i<=n;i++)
100     {
101         int x;
102         scanf("%d%d%lld",&x,&a[i],&v[i]);
103         add(x,i);
104     }
105     for(int i=1;i<=m;i++)
106     {
107         ll x;
108         scanf("%lld%d",&x,&s[i]);
109         mp[i].x=x;
110         mp[i].mul=1;
111         int fx=fa[s[i]];
112         fa[s[i]]=merge(fx,i);
113     }
114     dfs(1,0);
115     for(int i=1;i<=n;i++)
116     {
117         printf("%d\n",siz[i]);
118     }
119     for(int i=1;i<=m;i++)
120     {
121         printf("%d\n",(ans[i]==-1)?(dep[s[i]]+1):ans[i]);
122     }
123     return 0;
124 }
View Code

非递归版

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <queue>
  7 #include <iostream>
  8 using namespace std;
  9 #define N 300005
 10 #define ll long long
 11 struct node
 12 {
 13     int ls,rs,dis;ll x,add,mul;
 14 }mp[N<<1];
 15 struct no
 16 {
 17     int to,next;
 18 }e[N];
 19 ll h[N],v[N];
 20 int head[N],cnt,fa[N],dep[N],a[N],siz[N],ans[N],s[N],n,m;
 21 void add(int x,int y)
 22 {
 23     e[cnt].to=y;
 24     e[cnt].next=head[x];
 25     head[x]=cnt++;
 26     return ;
 27 }
 28 void PushDown(int x)
 29 {
 30     if(mp[x].mul!=1)
 31     {
 32         mp[mp[x].ls].x*=mp[x].mul;
 33         mp[mp[x].rs].x*=mp[x].mul;
 34         mp[mp[x].ls].mul*=mp[x].mul;
 35         mp[mp[x].rs].mul*=mp[x].mul;
 36         mp[mp[x].ls].add*=mp[x].mul;
 37         mp[mp[x].rs].add*=mp[x].mul;
 38         mp[x].mul=1;
 39     }
 40     if(mp[x].add)
 41     {
 42         if(mp[x].ls)
 43             mp[mp[x].ls].x+=mp[x].add,mp[mp[x].ls].add+=mp[x].add;
 44         if(mp[x].rs)
 45             mp[mp[x].rs].x+=mp[x].add,mp[mp[x].rs].add+=mp[x].add;
 46         mp[x].add=0;
 47     }
 48 }
 49 int merge(int x,int y)
 50 {
 51     if(!x)return y;
 52     if(!y)return x;
 53     if(mp[x].x>mp[y].x)swap(x,y);
 54     PushDown(x);
 55     mp[x].rs=merge(mp[x].rs,y);
 56     if(mp[mp[x].rs].dis>mp[mp[x].ls].dis)swap(mp[x].ls,mp[x].rs);
 57     mp[x].dis=mp[mp[x].rs].dis+1;
 58     return x;
 59 }
 60 int f[N];
 61 void dfs(int x)
 62 {
 63     f[1]=0;
 64     while(x)
 65     {
 66         int son=0;
 67         for(int i=head[x];i!=-1;i=e[i].next)
 68         {
 69             int to1=e[i].to;
 70             if(to1!=f[x])
 71             {
 72                 f[to1]=x;
 73                 dep[to1]=dep[x]+1;
 74                 head[x]=e[i].next;
 75                 x=to1;
 76                 son=1;
 77                 break;
 78             }
 79         }
 80         if(!son)
 81         {
 82             if(!fa[x])
 83             {
 84                 x=f[x];
 85                 continue;
 86             } 
 87             int fx=fa[x];
 88             while(mp[fx].x<h[x])
 89             {
 90                 PushDown(fx);
 91                 fa[x]=merge(mp[fx].ls,mp[fx].rs);
 92                 siz[x]++;
 93                 ans[fx]=dep[s[fx]]-dep[x];
 94                 fx=fa[x];
 95                 if(!fx)break;
 96             }
 97             if(!fx)
 98             {
 99                 x=f[x];
100                 continue;
101             } 
102             if(a[x])
103             {
104                 mp[fx].x*=v[x];
105                 mp[fx].mul*=v[x];
106                 mp[fx].add*=v[x];
107             }else
108             {
109                 mp[fx].x+=v[x];
110                 mp[fx].add+=v[x];
111             }
112             fx=fa[f[x]];
113             int fy=fa[x];
114             fa[f[x]]=merge(fx,fy);
115             x=f[x];
116         }
117     }
118     return ;
119 }
120 int main()
121 {
122     memset(head,-1,sizeof(head));
123     memset(ans,-1,sizeof(ans));
124     scanf("%d%d",&n,&m);
125     for(int i=1;i<=n;i++)scanf("%lld",&h[i]);
126     for(int i=2;i<=n;i++)
127     {
128         int x;
129         scanf("%d%d%lld",&x,&a[i],&v[i]);
130         add(x,i);
131     }
132     for(int i=1;i<=m;i++)
133     {
134         ll x;
135         scanf("%lld%d",&x,&s[i]);
136         mp[i].x=x;
137         mp[i].mul=1;
138         int fx=fa[s[i]];
139         fa[s[i]]=merge(fx,i);
140     }
141     dfs(1);
142     for(int i=1;i<=n;i++)
143     {
144         printf("%d\n",siz[i]);
145     }
146     for(int i=1;i<=m;i++)
147     {
148         printf("%d\n",(ans[i]==-1)?(dep[s[i]]+1):ans[i]);
149     }
150     return 0;
151 }
View Code

bfs版没有写...

posted @ 2018-04-20 14:35  Winniechen  阅读(238)  评论(0编辑  收藏  举报