제출 #1340181

#제출 시각아이디문제언어결과실행 시간메모리
1340181alexddMigration Plan (JOI25_migration)C++20
42 / 100
2163 ms824416 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXV = 4e6 + 5;
const int MAXN = 2e6 + 5;
int val[MAXV];
int tin[MAXV], tout[MAXV], depth[MAXV];

/*int anc[MAXN][21];
int myanc(int x, int d)
{
    for(int b=0;b<21;b++)
        if((1<<b)&d)
            x = anc[x][b];
    return x;
}*/

struct GROUP
{
    vector<int> aib;
    int qry_aib(int poz)
    {
        poz++;
        int sum = 0;
        for(int i=poz;i>0;i-=(i&(-i)))
            sum += aib[i];
        return sum;
    }
    void upd_aib(int poz, int newv)
    {
        poz++;
        for(int i=poz;i<aib.size();i+=(i&(-i)))
            aib[i] += newv;
    }

    int lazy_up = -1;
    int my_depth;

    vector<pair<int,int>> nodes;//{tin, nod} sorted after tin
    void init(vector<pair<int,int>> myv, int init_depth)
    {
        nodes = myv;
        lazy_up = my_depth = init_depth;

        aib.resize(nodes.size() + 3, 0);
        for(int i=0;i<nodes.size();i++)
            upd_aib(i, val[nodes[i].second]);
    }

};

int who[MAXN];//who[d] = which group is on depth d
GROUP comp[MAXV];
void unite(int idx, int idy, int newd)//merge the group with idy into the group with idx
{
    assert(who[newd] == idx);
    assert(comp[idx].my_depth != comp[idy].my_depth);

    if(comp[idx].my_depth > comp[idy].my_depth)
    {
        who[newd] = idy;
        swap(idx, idy);
    }

    for(auto [mytin,y]:comp[idy].nodes)
    {
        int poz = lower_bound(comp[idx].nodes.begin(), comp[idx].nodes.end(), make_pair(mytin, 0LL)) - comp[idx].nodes.begin() - 1;
        assert(0 <= poz && poz < comp[idx].nodes.size());

        comp[idx].upd_aib(poz, val[y]);
        val[comp[idx].nodes[poz].second] += val[y];
        val[y] = 0;
    }
}
int query(int id, int init_nod)
{
    int le = lower_bound(comp[id].nodes.begin(), comp[id].nodes.end(), make_pair(tin[init_nod], 0LL)) - comp[id].nodes.begin();
    int ri = lower_bound(comp[id].nodes.begin(), comp[id].nodes.end(), make_pair(tout[init_nod] + 1, 0LL)) - comp[id].nodes.begin() - 1;
    return comp[id].qry_aib(ri) - comp[id].qry_aib(le - 1);
}

int n, timer;
int parent[MAXN];
vector<int> con[MAXN];
vector<pair<int,int>> ofdepth[MAXN];
void dfs(int nod)
{
    tin[nod] = ++timer;
    for(int adj:con[nod])
    {
        depth[adj] = depth[nod] + 1;
        dfs(adj);
    }
    tout[nod] = timer;
}
signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        cin>>parent[i];
        con[parent[i]].push_back(i);
    }
    for(int i=1;i<=n;i++)
        cin>>val[i];
    dfs(1);
    for(int i=1;i<=n;i++)
        ofdepth[depth[i]].push_back({tin[i], i});
    for(int d=0;d<n;d++)
    {
        if(ofdepth[d].empty())
        {
            who[d] = -1;
        }
        else
        {
            sort(ofdepth[d].begin(), ofdepth[d].end());
            who[d] = d;
            comp[d].init(ofdepth[d], d);
        }
    }
    int q;
    cin>>q;
    while(q--)
    {
        int tip;
        cin>>tip;
        if(tip == 1)
        {
            int x,y;
            cin>>x>>y;
            swap(x, y);
            assert(x < y);
            if(who[y] == -1)
                continue;
            if(who[x] == -1)
            {
                comp[who[y]].lazy_up = x;
                who[x] = who[y];
                who[y] = -1;
            }
            else
            {
                unite(who[x], who[y], x);
                who[y] = -1;
            }
        }
        else if(tip == 2)
        {

        }
        else
        {
            assert(tip == 3);
            int b;
            cin>>b;
            if(who[depth[b]] == -1)
                cout<<0<<"\n";
            else
                cout<<query(who[depth[b]], b)<<"\n";
        }
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...