左偏树0pts求助
查看原帖
左偏树0pts求助
328935
calmsGZ省队2024楼主2023/3/2 21:17
#include<bits/stdc++.h>

using namespace std;
#define int long long
int n,m;
int root[300005];
int defen[300005];
int f[300005];
int a[300005];
int v[300005];
int ans[300005];
vector<int>son[300005]; 
int Dep[300005];
int dead[300004];
struct node{
    int l,r;
    int anst;
    int mak;
    int add;
    int ans;
    int dead;
    int ability;
    int dist;
}tree[300005];
int s[300005];
int c[300005];

void pushdown(int p){
    if(tree[p].add==0&&tree[p].mak==1){
        return;
    }
    if(tree[p].l){
        tree[tree[p].l].mak*=tree[p].mak;
        tree[tree[p].l].add*=tree[p].mak;
        tree[tree[p].l].add+=tree[p].add;
        tree[tree[p].l].ability*=tree[p].mak;
        tree[tree[p].l].ability+=tree[p].add;
    }
    if(tree[p].r){
        tree[tree[p].r].mak*=tree[p].mak;
        tree[tree[p].r].add*=tree[p].mak;       
        tree[tree[p].r].add+=tree[p].add;
        tree[tree[p].r].ability*=tree[p].mak;
        tree[tree[p].r].ability+=tree[p].add;
    }
    tree[p].mak=1;
    tree[p].add=0; 
}

int merge(int x,int y){
    if(!x||!y){
        return x^y;
    } 
    pushdown(x);
    pushdown(y);
    if(tree[x].ability>tree[y].ability)swap(x,y);
    tree[x].r=merge(tree[x].r,y);
    if(tree[tree[x].l].dist<tree[tree[x].r].dist){
        swap(tree[x].l,tree[x].r);
    }
    tree[x].dist=tree[tree[x].r].dist+1;
    return x;
}

signed main(){
    scanf("%lld%lld",&n,&m);
//  tree[0].ability=1000000000000000000;
    for(int i=1;i<=n;i++){
        scanf("%lld",&defen[i]);
        root[i]=-1;
    }
    Dep[1]=1;
    tree[0].dist=-1;
    for(int i=2;i<=n;i++){
        scanf("%lld%lld%lld",&f[i],&a[i],&v[i]);
        Dep[i]=Dep[f[i]]+1;
    }
    for(int i=1;i<=m;i++){
        scanf("%lld%lld",&s[i],&c[i]);
        if(root[c[i]]!=-1)
            root[c[i]]=merge(root[c[i]],i);
        else
            root[c[i]]=i;
        tree[i].ability=s[i];
        tree[i].mak=1;
    //  cout<<c[i]<<' '<<root[c[i]]<<endl;
    }
    for(int i=n;i>=1;i--){
        while(root[i]!=-1){
            if(tree[root[i]].ability<defen[i]){
                tree[root[i]].dead=i;
                pushdown(root[i]);
                if(!tree[root[i]].l)root[i]=-1;
                else root[i]=merge(tree[root[i]].l,tree[root[i]].r);
            }else break;
        }
        if(i==1)break;
        if(root[i]==-1)continue;
        if(a[i]){
            tree[root[i]].mak*=v[i];
            tree[root[i]].add*=v[i];
            tree[root[i]].ability*=v[i];
        }else{
            tree[root[i]].add+=v[i];
            tree[root[i]].ability+=v[i];
        }
        pushdown(root[i]);
        if(root[f[i]]==-1)root[f[i]]=root[i];
        else root[f[i]]=merge(root[f[i]],root[i]);
    }
    for(int i=1;i<=m;i++){
        ans[tree[i].dead]++;
    }
    for(int i=1;i<=n;i++){
        printf("%lld\n",ans[i]);
    }
    for(int i=1;i<=m;i++){
    //  cout<<Dep[c[i]]<<" "<<Dep[tree[i].dead]<<endl;
        printf("%lld\n",Dep[c[i]]-Dep[tree[i].dead]);
    }
    return 0;
} 
2023/3/2 21:17
加载中...