您的位置:首页 > 其它

BZOJ 4003 城池攻占

2016-05-13 17:30 267 查看
可并堆。打标记。

注意细节。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define maxv 300500
#define maxe 300500
using namespace std;
struct edge
{
long long v,nxt;
}e[maxe];
set <long long> s[maxv];
set <long long> ::iterator it;
long long n,m,h[maxv],fath[maxv],a[maxv],v[maxv],w[maxv],c[maxv],val[maxv];
long long tree[maxv][3],dfl[maxv],dis[maxv],nume=0,l1[maxv],l2[maxv];
long long ans1[maxv],ans2[maxv],top[maxv],g[maxv];
bool vis[maxv];
void addedge(long long u,long long v)
{
e[++nume].v=v;
e[nume].nxt=g[u];
g[u]=nume;
}
void pushdown(long long x)
{
long long ls=tree[x][1],rs=tree[x][2];
l1[ls]=l1[ls]*l2[x]+l1[x];
l1[rs]=l1[rs]*l2[x]+l1[x];
l2[ls]*=l2[x];
l2[rs]*=l2[x];
val[ls]=val[ls]*l2[x]+l1[x];
val[rs]=val[rs]*l2[x]+l1[x];
l1[x]=0;l2[x]=1;
}
void pushup(long long x)
{
long long ls=tree[x][1],rs=tree[x][2];
if (dfl[ls]<dfl[rs]) swap(tree[x][1],tree[x][2]);
if (rs==0) dfl[x]=0;
else dfl[x]=dfl[rs]+1;
}
long long merge(long long a,long long b)
{
if (a==0) return b;
if (b==0) return a;
if (val[a]>val[b]) swap(a,b);
pushdown(a);
tree[a][2]=merge(tree[a][2],b);
pushup(a);
return a;
}
long long pop(long long x)
{
long long ls=tree[x][1],rs=tree[x][2];
pushdown(x);
tree[x][1]=0;tree[x][2]=0;
return merge(ls,rs);
}
void dfs1(long long x)
{
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
dis[v]=dis[x]+1;
dfs1(v);
}
}
void dfs2(long long x)
{
for (long long i=g[x];i;i=e[i].nxt)
dfs2(e[i].v);
long long root=-1;
for (it=s[x].begin();it!=s[x].end();it++)
{
long long now=*it;
if (root==-1) root=now;
else root=merge(root,now);
}
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if (top[v]<=0) continue;
if (root==-1) root=top[v];
else root=merge(root,top[v]);
}
long long cnt=0;
while ((val[root]<h[x]) && (root>=1))
{
ans2[root]=dis[c[root]]-dis[x];
vis[root]=true;
root=pop(root);
cnt++;
}
ans1[x]=cnt;
if (a[x]==0) {l1[root]+=v[x];val[root]+=v[x];}
else {l2[root]*=v[x];l1[root]*=v[x];val[root]*=v[x];}
top[x]=root;
}
int main()
{
memset(vis,false,sizeof(vis));
scanf("%lld%lld",&n,&m);
fill(l2+1,l2+m+1,1);
for (long long i=1;i<=n;i++)
scanf("%lld",&h[i]);
for (long long i=2;i<=n;i++)
{
scanf("%lld%lld%lld",&fath[i],&a[i],&v[i]);
addedge(fath[i],i);
}
for (long long i=1;i<=m;i++)
{
scanf("%lld%lld",&w[i],&c[i]);
s[c[i]].insert(i);
val[i]=w[i];
}
dfs1(1);
dfs2(1);
for (long long i=1;i<=n;i++) printf("%lld\n",ans1[i]);
for (long long i=1;i<=m;i++)
{
if ((ans2[i]==0) && (vis[i]==false)) printf("%lld\n",dis[c[i]]+1);
else printf("%lld\n",ans2[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: