记录编号 488711 评测结果 AAAEAAAAA
题目名称 [JLOI 2015] 城池攻占 最终得分 88
用户昵称 GravatarMayuri 是否通过 未通过
代码语言 C++ 运行时间 2.017 s
提交时间 2018-02-23 22:17:31 内存使用 26.74 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

#define ll long long
#define mem(Arr,x) memset(Arr,x,sizeof(Arr))

const int maxN=300100;
const int inf=2147483647;

class Heap
{
public:
    ll key,plus,mul;
    int ch[2],dis;
    Heap()
        {
            plus=0;mul=1;
            return;
        }
};

int n,m;
int edgecnt=-1,Head[maxN],Next[maxN*2],V[maxN*2];
int Id[maxN];
ll Def[maxN],Opt[maxN],Val[maxN],Depth[maxN];
int St[maxN],Ed[maxN],Fail[maxN];
Heap H[maxN];

int Merge(int r1,int r2);
void PushDown(int rt);
void Mark(int rt,ll plus,ll mul);
void dfs(int u);

int main()
{
    freopen("fall.in","r",stdin);freopen("fall.out","w",stdout);
    mem(Head,-1);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lld",&Def[i]);
    for (int i=2;i<=n;i++)
    {
        int fa;scanf("%d%lld%lld",&fa,&Opt[i],&Val[i]);
        edgecnt++;Next[edgecnt]=Head[fa];Head[fa]=edgecnt;V[edgecnt]=i;
    }
    for (int i=1;i<=m;i++)
    {
        scanf("%lld%d",&H[i].key,&St[i]);
        if (Id[St[i]]==0) Id[St[i]]=i;
        else Id[St[i]]=Merge(Id[St[i]],i);
    }
    Depth[1]=1;dfs(1);
    for (int i=1;i<=n;i++) printf("%d\n",Fail[i]);
    for (int i=1;i<=m;i++) printf("%lld\n",Depth[St[i]]-Depth[Ed[i]]);
    return 0;
}

int Merge(int r1,int r2)
{
    if (r1==0) return r2;
    if (r2==0) return r1;
    PushDown(r1);PushDown(r2);
    if (H[r1].key>H[r2].key) swap(r1,r2);
    H[r1].ch[1]=Merge(H[r1].ch[1],r2);
    if (H[H[r1].ch[0]].dis<H[H[r1].ch[1]].dis) swap(H[r1].ch[0],H[r1].ch[1]);
    if (H[r1].ch[1]) H[r1].dis=H[H[r1].ch[1]].dis+1;
    else H[r1].dis=0;
    return r1;
}

void PushDown(int rt)
{
    if (H[rt].ch[0]) Mark(H[rt].ch[0],H[rt].plus,H[rt].mul);
    if (H[rt].ch[1]) Mark(H[rt].ch[1],H[rt].plus,H[rt].mul);
    H[rt].mul=1;H[rt].plus=0;return;
}

void Mark(int rt,ll plus,ll mul)
{
    H[rt].key=H[rt].key*mul+plus;
    H[rt].plus=H[rt].plus*mul+plus;
    H[rt].mul=H[rt].mul*mul;
    return;
}

void dfs(int u)
{
    for (int i=Head[u];i!=-1;i=Next[i])
        Depth[V[i]]=Depth[u]+1,dfs(V[i]);
    for (int i=Head[u];i!=-1;i=Next[i])
    {
        if (Id[V[i]]==0) continue;
        if (Id[u]==0) Id[u]=Id[V[i]];
        else Id[u]=Merge(Id[u],Id[V[i]]);
    }
    while ((Id[u])&&(H[Id[u]].key<Def[u]))
    {
        Fail[u]++;Ed[Id[u]]=u;
        PushDown(Id[u]);Id[u]=Merge(H[Id[u]].ch[0],H[Id[u]].ch[1]);
    }
    if (Id[u])
    {
        if (Opt[u]==0) Mark(Id[u],Val[u],1);
        if (Opt[u]==1) Mark(Id[u],0,Val[u]);
    }
    return;
}