답안 #642639

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
642639 2022-09-20T09:51:54 Z Tenis0206 Arboras (RMI20_arboras) C++11
0 / 100
342 ms 35052 KB
#include <bits/stdc++.h>
#define int long long

using namespace std;

const int Mod = 1e9 + 7;

struct aint
{
    int ai[500005],lazy[500005];
    void propag(int nod, int a, int b)
    {
        if(lazy[nod]==0)
        {
            return;
        }
        int mij = (a + b) >> 1;
        ai[nod*2] += lazy[nod] * (mij - a + 1);
        ai[nod*2+1] += lazy[nod] * (b - mij);
        lazy[nod*2] += lazy[nod];
        lazy[nod*2+1] += lazy[nod];
        lazy[nod] = 0;
    }
    void update(int ua, int ub, int val, int nod, int a, int b)
    {
        if(ua<=a && ub>=b)
        {
            ai[nod] += val * (b - a + 1);
            lazy[nod] += val;
            return;
        }
        propag(nod,a,b);
        int mij = (a + b) >> 1;
        if(ua<=mij)
        {
            update(ua,ub,val,nod*2,a,mij);
        }
        if(ub>mij)
        {
            update(ua,ub,val,nod*2+1,mij+1,b);
        }
        ai[nod] = ai[nod*2] + ai[nod*2+1];
    }
    int query(int poz, int nod, int a, int b)
    {
        if(a==b)
        {
            return ai[nod];
        }
        int mij = (a + b) >> 1;
        if(poz<=mij)
        {
            return query(poz,nod*2,a,mij);
        }
        return query(poz,nod*2+1,mij+1,b);
    }
};

aint ai,ai2;

int n,q;

int w[100005],Mx[100005];
int l[100005],t[100005],c[100005],poz[100005],lvl[100005];

int cnt = 0, paths = 1;

int d[100005];

pair<int,int> Max[100005],Max2[100005];

vector<int> G[100005];

set<pair<int,int>,greater<pair<int,int>>>s[100005];

vector<int> se;

void get_w(int nod, int dad = 0)
{
    w[nod] = 1;
    for(auto it : G[nod])
    {
        if(it==dad)
        {
            continue;
        }
        get_w(it,nod);
        w[nod] += w[it];
        if(w[it] > w[Mx[nod]])
        {
            Mx[nod] = it;
        }
    }
}

void get_paths(int nod, int dad = 0, int level = 1)
{
    poz[nod] = (++cnt);
    l[nod] = paths;
    lvl[nod] = level;
    t[nod] = dad;
    if(G[nod].size()==1 && nod!=1)
    {
        return;
    }
    get_paths(Mx[nod],nod,level+1);
    for(auto it : G[nod])
    {
        if(it==dad || it==Mx[nod])
        {
            continue;
        }
        ++paths;
        c[paths] = it;
        get_paths(it,nod,level+1);
    }
}

void dfs(int nod, int dad = 0)
{
    for(auto it : G[nod])
    {
        if(it==dad)
        {
            continue;
        }
        dfs(it,nod);
        if(Max[it].first + d[it] > Max[nod].first)
        {
            Max2[nod] = Max[nod];
            Max[nod].first = Max[it].first + d[it];
            Max[nod].second = it;
        }
        else if(Max[it].first + d[it] > Max2[nod].first)
        {
            Max2[nod].first = Max[it].first + d[it];
            Max2[nod].second = it;
        }
    }
    for(auto it : G[nod])
    {
        if(it==dad || it==Max[nod].second)
        {
            continue;
        }
        se.push_back(it);
    }
}

void add_se(int nod)
{
    s[l[nod]].insert({lvl[nod],nod});
}

void remove_se(int nod)
{
    auto it = s[l[nod]].lower_bound({lvl[nod],nod});
    s[l[nod]].erase(it);
}

int find_next_se(int nod)
{
    while(nod)
    {
        auto it = s[l[nod]].lower_bound({lvl[nod],nod});
        if(it!=s[l[nod]].end())
        {
            return it->second;
        }
        nod = t[c[l[nod]]];
    }
    return 1;
}

void update_arb(int x, int y, int val)
{
    if(lvl[x] > lvl[y])
    {
        return;
    }
    while(l[x]!=l[y])
    {
        ai.update(poz[c[l[y]]],poz[y],+val,1,1,n);
        y = t[c[l[y]]];
    }
    ai.update(poz[x],poz[y],+val,1,1,n);
}

void update(int nod, int val)
{
    while(nod!=1)
    {
        int anc = find_next_se(nod);
        update_arb(anc,t[nod],+val);
        nod = anc;
        if(nod==1)
        {
            break;
        }
        int cnd = ai.query(poz[nod],1,1,n) + d[nod];
        int dad = t[nod];
        int Maxdad = ai.query(poz[dad],1,1,n);
        int Max2dad = ai2.query(poz[dad],1,1,n);
        if(cnd <= Max2dad)
        {
            break;
        }
        if(cnd > Maxdad)
        {
            remove_se(nod);
            add_se(Max[dad].second);
            ai2.update(poz[dad],poz[dad],Maxdad-Max2dad,1,1,n);
            Max2[dad].second = Max[dad].second;
            ai.update(poz[dad],poz[dad],cnd-Maxdad,1,1,n);
            Max[dad].second = nod;
            val = cnd - Maxdad;
            nod = dad;
        }
        else if(cnd > Max2dad)
        {
            Max2[dad].second = nod;
            ai2.update(poz[dad],poz[dad],cnd-Max2dad,1,1,n);
            break;
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
  //  freopen("nr.in","r",stdin);
  //  freopen("nr.out","w",stdout);
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int t;
        cin>>t;
        ++t;
        G[i].push_back(t);
        G[t].push_back(i);
    }
    for(int i=2;i<=n;i++)
    {
        cin>>d[i];
    }
    dfs(1);
    get_w(1);
    c[1] = 1;
    get_paths(1);
    for(auto it : se)
    {
        add_se(it);
    }
    for(int i=1;i<=n;i++)
    {
        ai.update(poz[i],poz[i],Max[i].first,1,1,n);
        ai2.update(poz[i],poz[i],Max2[i].first,1,1,n);
    }
    cout<<(ai.ai[1] + ai2.ai[1]) % Mod<<'\n';
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        int nod,val;
        cin>>nod>>val;
        ++nod;
        d[nod] += val;
        update(nod,val);
        cout<<(ai.ai[1] + ai2.ai[1]) % Mod<<'\n';
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 7636 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 342 ms 34228 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 206 ms 35052 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 7636 KB Output isn't correct
2 Halted 0 ms 0 KB -