제출 #1343765

#제출 시각아이디문제언어결과실행 시간메모리
1343765huypham2009Dynamic Diameter (CEOI19_diameter)C++17
49 / 100
5091 ms16748 KiB
#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int maxn = 1e5 + 5;
int n, q;
long long w;
namespace subtask12{
    
    struct edge{
        int u, v;
        long long w;
    };
    
    vector<pair<int, long long>> g[5005], ed;
    
    long long dist[5005], ans, last = 0;
    
    void readinput()
    {
        for(int i = 1; i < n; i++)
        {
            int u, v;
            long long w;
            cin >> u >> v >> w;
            ed.push_back({u, v});
            g[u].push_back({v, w});
            g[v].push_back({u, w});
        }
    }
    
    void dp(int u, int p)
    {
        dist[u] = 0;
        long long maxx = 0;
        for(pair<int, long long> res : g[u])
        {
            int v = res.first;
            if(v == p) continue;
            dp(v, u);
            long long weight = res.second + dist[v];
            ans = max(ans, maxx + weight);
            maxx = max(maxx, weight);
        }
        dist[u] = maxx;
    }
    
    void solve()
    {
        readinput();
        
        while(q--)
        {
            ans = 0;
            int d;
            long long e;
            cin >> d >> e;
            d = (last + d) % (n - 1);
            e = (e + last) % w;
            int u = ed[d].first, v = ed[d].second;
            for(pair<int, long long> &res : g[u])
            {
                if(res.first == v) res.second = e;
            }
            for(pair<int, long long> &res : g[v])
            {
                if(res.first == u) res.second = e;
            }
            dp(1, 1);
            cout << ans << '\n';
            last = ans;
        }
    }
}
vector<pair<int,long long>> g[maxn];

struct edge{
    int u, v;
    long long w;
};

vector<edge> ed;

namespace subtask3
{
    int cnt[maxn];
    bool check()
    {
        for(edge x : ed)
        {
            cnt[x.u]++;
            cnt[x.v]++;
        }
        for(int i = 1; i <= n; i++) if(cnt[i] == n - 1) return 1;
        return 0;
    }
    
    long long last = 0;
    pair<long long, long long> st[4 * maxn];
    void build(int v, int l, int r)
    {
        if(l == r)
        {
            st[v].first = ed[l - 1].w;
            st[v].second = 0;
            return;
        }
        
        int mid = (l + r) >> 1;
        
        build(v << 1, l, mid);
        build(v << 1 | 1, mid + 1, r);
        
        st[v].first = max(st[v << 1].first, st[v << 1 | 1].first);
        st[v].second = max({st[v << 1].second, st[v << 1 | 1].second, min(st[v << 1].first, st[v << 1 | 1].first)});
    }
    
    void update(int v, int l, int r, int pos, long long val)
    {
        if(l > pos || r < pos) return;
        
        if(l == r)
        {
            st[v].first = val;
            return;
        }
        
        int mid = (l + r) >> 1;
        
        update(v << 1, l, mid, pos, val);
        update(v << 1 | 1, mid + 1, r, pos, val);
        
        st[v].first = max(st[v << 1].first, st[v << 1 | 1].first);
        st[v].second = max({st[v << 1].second, st[v << 1 | 1].second, min(st[v << 1].first, st[v << 1 | 1].first)});
    }
    
    pair<long long, long long> get(int v, int l, int r, const int &b, const int &e)
    {
        if(l > e || r < b) return {0, 0};
        
        if(l >= b && r <= e) return st[v];
        
        int mid = (l + r) >> 1;
        
        pair<long long, long long> res, maxl = get(v << 1, l, mid + 1, b, e), maxr = get(v << 1 | 1, mid + 1, r, b, e);
        res.first = max(maxl.first, maxr.first);
        res.second = max({maxl.second, maxr.second, min(maxl.first, maxr.first)});
        return res;
    }
    
    void solve()
    {
        build(1, 1, n - 1);
        
        while(q--)
        {
            int d;
            long long e;
            
            cin >> d >> e;
            
            d = (last + d) % (n - 1);
            e = (last + e) % w;
            
            update(1, 1, n - 1, d + 1, e);
            
            pair<long long, long long> res =  get(1, 1, n - 1, 1, n - 1);
            last = res.first + res.second;
            cout << last << '\n';
        }
    }
}
namespace subtask4
{
    int num[maxn], tail[maxn], Par[maxn], timeDfs = 0;
    pair<int, int> depth[maxn];
    long long last = 0, dist[maxn], ans[maxn];
    
    void pre(int u, int p)
    {
        for(pair<int, long long> v : g[u])
        {
            if(v.first == p) continue;
            Par[v.first] = u;
            depth[v.first].first = depth[u].first + 1;
            depth[v.first].second = v.first;
            pre(v.first, u);
        }
        for(pair<int, long long> v : g[u])
        {
            depth[u] = max(depth[u], depth[v.first]);
        }
    }
    void dfs(int u, int p)
    {
        num[u] = tail[u] = ++timeDfs;
        for(pair<int, long long> v : g[u])
        {
            if(v.first == p) continue;
            
            dfs(v.first, u);
            
            tail[u] = max(tail[u], tail[v.first]);
        }
    }
    
    void predp(int u, int p)
    {
        dist[u] = 0;
        ans[u] = 0;
        long long maxx = 0;
        for(pair<int, long long> res : g[u])
        {
            int v = res.first;
            if(v == p) continue;
            
            predp(v, u);
            
            long long weight = res.second + dist[v];
            
            ans[u] = max(ans[u], weight + maxx);
            maxx = max(maxx, weight);
            ans[u] = max(ans[u], ans[v]);
        }
        dist[u] = maxx;
    }
    
    void recal(int u, int p, int l, int r)
    {
        ans[u] = 0;
        dist[u] = 0;
        long long maxx = 0;
        for(pair<int, long long> res : g[u])
        {
            int v = res.first;
            
            if(v == p) continue;
            
            if(num[v] <= l && r <= tail[v]) recal(v, u, l, r);
            
            long long weight = res.second + dist[v];
            
            ans[u] = max(ans[u], weight + maxx);
            ans[u] = max(ans[u], ans[v]);
            maxx = max(maxx, weight);
        }
        dist[u] = maxx;
    }
    
    int new_root()
    {
        int maxx = 0, u, maxdepth = 0;
        for(pair<int, long long> v : g[1])
        {
            maxdepth = max(maxdepth, maxx + depth[v.first].first);
            if(depth[v.first].first > maxx)
            {
                // cout << depth[v.first].second << ' ';
                maxx = depth[v.first].first;
                u = depth[v.first].second;
            }
        }
        // cout << u << '\n';
        for(int i = (maxdepth + 1) / 2 - 1; i >= 1; i--) u = Par[u];
        
        return u;
    }
    void solve()
    {
        for(int i = 1; i <= n; i++)
        {
            sort(g[i].begin(), g[i].end());
        }
        // depth[1] = 1;
        pre(1, 1);
        // for(int i = 1; i <= n; i++) cout << i << ' ' << depth[i].first << ' ' << depth[i].second << '\n';
        int root = new_root();
        // cout << root << '\n';
        dfs(root, root);
        predp(root, root);
        while(q--)
        {
            int d;
            long long e;
            
            cin >> d >> e;
            
            d = (last + d) % (n - 1);
            e = (e + last) % w;
            
            int u = ed[d].u, v = ed[d].v;
            
            pair<int, long long> res = {v, -1};
            auto it = lower_bound(g[u].begin(), g[u].end(), res);
            (*it).second = e;
            
            res = {u, -1};
            it = lower_bound(g[v].begin(),g[v].end(), res);
            (*it).second = e;
            
            // for(pair<int, long long> &res : g[u])
            // {
            //     if(res.first == v) res.second = e;
            // }
            // for(pair<int, long long> &res : g[v])
            // {
            //     if(res.first == u) res.second = e;
            // }
            
            if(tail[u] - num[u] > tail[v] - num[v]) swap(u, v);
            
            recal(root, root, num[u], tail[u]);
            
            cout << ans[root] << '\n';
            
            last = ans[root];
        }
    }
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> q >> w;
    for(int i = 1; i < n; i++)
    {
        int u, v;
        long long w;
        cin >> u >> v >> w;
        ed.push_back({u, v, w});
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }
    
    if(subtask3::check())
    {
        subtask3::solve();
        return 0;
    }
    else subtask4::solve();
    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...