답안 #478002

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
478002 2021-10-05T02:57:27 Z bonopo Dynamic Diameter (CEOI19_diameter) C++17
7 / 100
5000 ms 68136 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define pb push_back
#define rc (i<<1)|1
#define lc (i<<1)
#define el "\n"
#define f first
#define s second

typedef long long ll;
const int MM=1e5+5, MOD=1e9+7, LOG=19;
int N, Q, W, sz[MM], bk[MM], pa[LOG][MM], in[LOG][MM], ot[LOG][MM], cp[LOG][MM], tp[LOG][MM], ct;
vector<int> adj[MM];
gp_hash_table<int,int> mp[MM];

struct node {
    ll lz;
    pair<ll,int> mx;
};

struct tree {
    vector<node> seg;
    int wt;

    void prop(int i, int l, int r) {
        if(l!=r) {
            seg[lc].lz+=seg[i].lz;
            seg[rc].lz+=seg[i].lz; }
        seg[i].mx.f+=seg[i].lz;
        seg[i].lz=0;
    }

    void build(int i, int sl, int sr) {
        if(sl==sr) {
            seg[i].mx={0,sl};
            return; }
        int m=sl+sr>>1;
        build(rc, m+1, sr);
        build(lc, sl, m);
        calc(i);
    }

    void calc(int i) {
        seg[i].mx=max(seg[lc].mx, seg[rc].mx);
    }

    void upd(int i, int sl, int sr, int l, int r, ll v) {
        if(l>sr || r<sl) return;
        if(l<=sl&&sr<=r) {
            seg[i].lz+=v;
            prop(i, sl, sr); return; }
        int m=sl+sr>>1;
        upd(rc, m+1, sr, l, r, v);
        upd(lc, sl, m, l, r, v);
        calc(i);
    }

    pair<ll,int> rmq(int i, int sl, int sr, int l, int r) {
        if(l>sr || r<sl) return {0,0};
        if(l<=sl&&sr<=r) return seg[i].mx;
        int m=sl+sr>>1;
        return max(rmq(lc, sl, m, l, r), rmq(rc, m+1, sr, l, r));
    }

    void init(int n) {
        wt=n;
        seg.resize(4*n+1);
        build(1, 1, n);
    }
} st[MM];

int crt(int u, int th, int fa) {
    for(int &v:adj[u]) if(v!=fa&&!bk[v]&&sz[v]>=th) {
        return crt(v, th, u); }
    return u;
}

void dfs(int u, int fa) {
    sz[u]=1;
    for(int &v:adj[u]) if(v!=fa&&!bk[v]) {
        dfs(v, u);
        sz[u]+=sz[v];
    }
}

void etr(int u, int fa, int lvl, int rt, int tv) {
    in[lvl][u]=++ct; cp[lvl][u]=rt; tp[lvl][u]=tv; mp[rt][ct]=u;
    for(int &v:adj[u]) if(v!=fa&&!bk[v]) {
        etr(v, u, lvl, rt, tv); }
    ot[lvl][u]=ct;
}

void rec(int rt, int nds, int fa=-1, int lvl=0) {
    dfs(rt, 0);

    // find centroid
  //  cout<<"centroid for "<<rt<<" nds "<<nds<<" lvl "<<lvl<<" is ";
    rt=crt(rt, nds/2, 0); pa[lvl][rt]=fa;
  //  cout<<rt<<el;

    bk[rt]=true; ct=0;

    // get ett
    cp[lvl][rt]=tp[lvl][rt]=rt;
    for(int &v:adj[rt]) if(!bk[v]) etr(v, rt, lvl, rt, v);

    // construct tree
    st[rt].init(nds);

    for(int &v:adj[rt]) if(!bk[v]) {
        rec(v, sz[v], rt, lvl+1);
    }
}

ll qry(int u, int v, ll val) {
    ll ret=0;

    // find smallest component
    int cur=0;
    while(cur<LOG-1&&cp[cur+1][u]!=0) ++cur;
  //  cout<<"iterating on "<<u<<" starting with "<<cur<<" delta "<<val<<el;

    // jump
    int crt=u;
    while(~cur) {
        // update edge
     //   cout<<"crt "<<crt<<el;

        if(cp[cur][u]==crt&&cp[cur][v]==crt) {
            int w=(in[cur][u]>in[cur][v]?u:v);

           // cout<<"level "<<cur<<" w "<<w<<" cent "<<crt<<" updating "<<in[cur][w]<<" "<<ot[cur][w]<<el;
            st[crt].upd(1, 1, st[crt].wt, in[cur][w], ot[cur][w], val);

            // query max
            auto x=st[crt].rmq(1, 1, st[crt].wt, 1, st[crt].wt);
            x.s=mp[crt][x.s];
           // cout<<"x value "<<x.f<<" "<<x.s<<" "<<tp[cur][x.s]<<" "<<in[cur][tp[cur][x.s]]<<" "<<ot[cur][tp[cur][x.s]]<<el;
            auto y=max(st[crt].rmq(1, 1, st[crt].wt, 1, in[cur][tp[cur][x.s]]-1), st[crt].rmq(1, 1, st[crt].wt, ot[cur][tp[cur][x.s]]+1, st[crt].wt));
            //cout<<"y value "<<y.f<<" "<<x.s<<el;

            ll cnd=x.f+y.f;
            ret=max(ret, cnd);
        }

        crt=pa[cur--][crt];
    }

    return ret;
}

int32_t main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>N>>Q>>W;
    vector<pair<ll,pair<int,int>>> edg;
    memset(pa, -1, sizeof(pa));
    for(int i=1; i<N; ++i) {
        ll u, v, w; cin>>u>>v>>w;
        adj[u].pb(v); adj[v].pb(u);
        edg.pb({w,{u,v}});
    }

    // preprocess
    rec(1, N);
    for(auto &e:edg) qry(e.s.f, e.s.s, e.f);

    ll last=0, e, w;
    for(int q=1; q<=Q; ++q) {
        cin>>e>>w;
        e=(e+last)%(N-1);
        w=(w+last)%W;
      //  cout<<"actual qry "<<e<<" "<<w<<el;

        last=qry(edg[e].s.f, edg[e].s.s, w-edg[e].f);
        cout<<last<<el; edg[e].f=w;
    }
}

// MM

Compilation message

diameter.cpp: In member function 'void tree::build(int, int, int)':
diameter.cpp:39:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   39 |         int m=sl+sr>>1;
      |               ~~^~~
diameter.cpp: In member function 'void tree::upd(int, int, int, int, int, ll)':
diameter.cpp:54:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   54 |         int m=sl+sr>>1;
      |               ~~^~~
diameter.cpp: In member function 'std::pair<long long int, int> tree::rmq(int, int, int, int, int)':
diameter.cpp:63:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   63 |         int m=sl+sr>>1;
      |               ~~^~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 25 ms 34380 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 25 ms 34380 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 34352 KB Output is correct
2 Correct 25 ms 34360 KB Output is correct
3 Correct 29 ms 34356 KB Output is correct
4 Correct 36 ms 34500 KB Output is correct
5 Correct 66 ms 34724 KB Output is correct
6 Correct 26 ms 34420 KB Output is correct
7 Correct 30 ms 34492 KB Output is correct
8 Correct 33 ms 34740 KB Output is correct
9 Correct 28 ms 34484 KB Output is correct
10 Correct 48 ms 34760 KB Output is correct
11 Correct 89 ms 35012 KB Output is correct
12 Correct 34 ms 36016 KB Output is correct
13 Correct 35 ms 36148 KB Output is correct
14 Correct 38 ms 36156 KB Output is correct
15 Correct 47 ms 36196 KB Output is correct
16 Correct 119 ms 36628 KB Output is correct
17 Correct 161 ms 67552 KB Output is correct
18 Correct 139 ms 67508 KB Output is correct
19 Correct 143 ms 67624 KB Output is correct
20 Correct 163 ms 67628 KB Output is correct
21 Correct 234 ms 68136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 33 ms 36316 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5072 ms 37568 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 25 ms 34380 KB Output isn't correct
2 Halted 0 ms 0 KB -