Submission #1232826

#TimeUsernameProblemLanguageResultExecution timeMemory
1232826Tenis0206Dynamic Diameter (CEOI19_diameter)C++20
73 / 100
1098 ms26644 KiB
#include <bits/stdc++.h>
#define int long long

using namespace std;

const int nmax = 1e5;

struct Edge
{
    int x, y, c;
};

int n, q, w;
Edge e[nmax + 5];
vector<pair<int,int>> G[nmax + 5];

int l[nmax + 5];
int t[nmax + 5];

int p[nmax + 5], u[nmax + 5];

int r[nmax + 5];

pair<int,int> ai[4 * nmax + 5];
int lazy[4 * nmax + 5];

pair<int,int> Merge(pair<int,int> a, pair<int,int> b)
{
    if(a > b)
    {
        return a;
    }
    return b;
}

void init(int nod, int a, int b)
{
    if(a == b)
    {
        ai[nod].second = l[a];
        return;
    }
    int mij = (a + b) >> 1;
    init(nod * 2, a, mij);
    init(nod * 2 + 1, mij + 1, b);
    ai[nod] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
}

void propag(int nod)
{
    if(lazy[nod] == 0)
    {
        return;
    }
    ai[nod * 2].first += lazy[nod];
    ai[nod * 2 + 1].first += lazy[nod];
    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].first += val;
        lazy[nod] += val;
        return;
    }
    propag(nod);
    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] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
}

pair<int,int> query(int qa, int qb, int nod, int a, int b)
{
    if(qa <= a && qb >=b)
    {
        return ai[nod];
    }
    propag(nod);
    int mij = (a + b) >> 1;
    if(qa <= mij && qb > mij)
    {
        return Merge(query(qa, qb, nod*2, a, mij), query(qa, qb, nod*2+1, mij+1, b));
    }
    if(qa <= mij)
    {
        return query(qa, qb, nod*2, a, mij);
    }
    return query(qa, qb, nod*2+1, mij+1, b);
}

bool subtask2()
{
#ifdef home
    return false;
#endif // home
    return (n <= 5000 && q <= 5000);
}

bool subtask3()
{
    for(int i=1; i<n; i++)
    {
        if(e[i].x != 1 && e[i].y != 1)
        {
            return false;
        }
    }
    return true;
}

bool subtask4()
{
    for(int i=1; i<n; i++)
    {
        if(e[i].y == 2 * e[i].x || e[i].y == 2 * e[i].x + 1)
        {
            continue;
        }
        if(e[i].x == 2 * e[i].y || e[i].x == 2 * e[i].y + 1)
        {
            continue;
        }
        return false;
    }
    return true;
}

int dfs(int nod, int dad = 0)
{
    l[nod] = 0;
    vector<int> lst;
    int rez = 0;
    for(auto it : G[nod])
    {
        if(it.first == dad)
        {
            continue;
        }
        rez = max(rez, dfs(it.first, nod));
        lst.push_back(l[it.first] + e[it.second].c);
        l[nod] = max(l[nod], l[it.first] + e[it.second].c);
    }
    sort(lst.begin(), lst.end(), greater<int>());
    if(lst.size() == 0)
    {
        r[nod] = rez;
        return rez;
    }
    if(lst.size() == 1)
    {
        rez = max(rez, lst.front());
        r[nod] = rez;
        return rez;
    }
    rez = max(rez, lst[0] + lst[1]);
    r[nod] = rez;
    return rez;
}

void solve2()
{
    int last = 0;
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        e[edge].c = val;
        last = dfs(1);
        cout<<last<<'\n';
    }
}

void solve3()
{
    int last = 0;
    multiset<int, greater<int>> s;
    for(int i=1; i<n; i++)
    {
        s.insert(e[i].c);
    }
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        auto it = s.lower_bound(e[edge].c);
        s.erase(it);
        s.insert(val);
        e[edge].c = val;
        last = 0;
        it = s.begin();
        last += *it;
        ++it;
        last += *it;
        cout<<last<<'\n';
    }
}

void solve4()
{
    int last = 0;
    dfs(1);
    multiset<int, greater<int>> s;
    for(int i=1; i<=n; i++)
    {
        s.insert(r[i]);
    }
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        e[edge].c = val;

        int nod = min(e[edge].x, e[edge].y);
        while(nod != 0)
        {
            auto er = s.lower_bound(r[nod]);
            s.erase(er);
            l[nod] = 0;
            vector<int> lst;
            for(auto it : G[nod])
            {
                if(it.first == nod / 2)
                {
                    continue;
                }
                lst.push_back(l[it.first] + e[it.second].c);
                l[nod] = max(l[nod], l[it.first] + e[it.second].c);
            }
            sort(lst.begin(), lst.end(), greater<int>());
            if(lst.size() == 0)
            {
                r[nod] = 0;
            }
            else if(lst.size() == 1)
            {
                r[nod] = lst.front();
            }
            else
            {
                r[nod] = lst[0] + lst[1];
            }
            s.insert(r[nod]);
            nod /= 2;
        }
        auto it = s.begin();
        last = *it;

        cout<<last<<'\n';
    }
}

int cnt = 0;

void euler(int nod, int dad = 0, int root = 0)
{
    p[nod] = (++cnt);
    l[cnt] = nod;
    t[nod] = dad;
    r[nod] = root;
    for(auto it : G[nod])
    {
        if(it.first == dad)
        {
            continue;
        }
        if(dad == 0)
        {
            euler(it.first, nod, it.first);
        }
        else
        {
            euler(it.first, nod, root);
        }
    }
    u[nod] = cnt;
}

void solve5()
{
    euler(1);
    init(1, 1, n);
    for(int i=1; i<n; i++)
    {
        if(e[i].y == t[e[i].x])
        {
            swap(e[i].x, e[i].y);
        }
        update(p[e[i].y], u[e[i].y], e[i].c, 1, 1, n);
    }
    int last = 0;
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        update(p[e[edge].y], u[e[edge].y], val - e[edge].c, 1, 1, n);
        e[edge].c = val;

        pair<int,int> Max1 = ai[1];
        pair<int,int> Max2 = {0, 0};
        if(p[r[Max1.second]] != 2)
        {
            Max2 = Merge(Max2, query(2, p[r[Max1.second]] - 1, 1, 1, n));
        }
        if(u[r[Max1.second]] != n)
        {
            Max2 = Merge(Max2, query(u[r[Max1.second]] + 1, n, 1, 1, n));
        }
        last = Max1.first + Max2.first;

        cout<<last<<'\n';
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef home
    freopen("nr.in","r",stdin);
    freopen("nr.out","w",stdout);
#endif // home
    cin>>n>>q>>w;
    for(int i=1; i<n; i++)
    {
        cin>>e[i].x>>e[i].y>>e[i].c;
        G[e[i].x].push_back({e[i].y, i});
        G[e[i].y].push_back({e[i].x, i});
    }
    if(subtask2())
    {
        solve2();
        return 0;
    }
    if(subtask3())
    {
        solve3();
        return 0;
    }
    if(subtask4())
    {
        solve4();
        return 0;
    }
    solve5();
    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...