萌新刚学OI,树剖求助qwq
查看原帖
萌新刚学OI,树剖求助qwq
245875
Ame__楼主2020/10/17 09:16

不知道为什么求KTHKTH写的不对,但是感觉自己写的妹啥问题(,求帮忙qwq

#include<bits/stdc++.h>
    
#define LL long long
    
#define _ 0
    
#define AME__DEBUG
    
#define LOG(FMT...) fprintf(stderr , FMT)
    
using namespace std;
    
/*Grievous Lady*/
    
const int BUF_SIZE = 1 << 12;
    
char buf[BUF_SIZE] , *buf_s = buf , *buf_t = buf + 1;
    
#define PTR_NEXT() \
{ \
    buf_s ++; \
    if(buf_s == buf_t) \
    { \
        buf_s = buf; \
        buf_t = buf + fread(buf , 1 , BUF_SIZE , stdin); \
    } \
}
    
#define mians(_s_) \
{ \
    while(!isalpha(*buf_s)) \
        PTR_NEXT(); \
    char register *_ptr_ = (_s_); \
    while(isalpha(*buf_s) || *buf_s == '-') \
    { \
        *(_ptr_ ++) = *buf_s; \
        PTR_NEXT(); \
    } \
    (*_ptr_) = '\0'; \
}
    
template <typename _n_> void mian(_n_ & _x_){
    while(*buf_s != '-' && !isdigit(*buf_s)) PTR_NEXT();
    bool register _nega_ = false; if(*buf_s == '-'){ _nega_ = true; PTR_NEXT(); }
    _x_ = 0; while(isdigit(*buf_s)){ _x_ = _x_ * 10 + *buf_s - '0'; PTR_NEXT(); } if(_nega_) _x_ = -_x_;
}
    
#define qwq 114514

const int kato = 1e5 + 10;

int t , n , x , y , z , k , rt = 1;

char opt[10];

template <typename _n_> bool cmax(_n_ &a , const _n_ &b){ return a < b ? a = b , 1 : 0; }
    
template <typename _n_> bool cmin(_n_ &a , const _n_ &b){ return a > b ? a = b , 1 : 0; }
    
namespace yuni{
    struct Edge{
        int to , dis;
        Edge *nxt;
    };

    struct Graph{
        Edge yuni[kato << 1] , *head[kato] , *tail;

        void clear() { memset(head , 0 , sizeof head); tail = yuni; }

        Graph() { clear(); }

        Edge *operator[](int x){ return head[x]; }

        void add(int x , int y , int z){ *tail = (Edge){y , z , head[x]}; head[x] = tail ++; }
    }Ire;

    int cnt , val[kato] , dfn[kato] , dep[kato] , size[kato] , son[kato] , fa[kato] , top[kato] , id[kato];

    void dfs1(int u , int f){
        fa[u] = f , size[u] = 1;
        dep[u] = dep[f] + 1;
        for(Edge *i = Ire[u] ; i ; i = i -> nxt){
            int v = i -> to;
            if(v == f) continue;
            dfs1(v , u);
            size[u] += size[v]; val[v] = i -> dis;
            if(!son[u] || size[v] > size[son[u]]) son[u] = v;
        }
    }

    void dfs2(int u , int f){
        top[u] = f , dfn[u] = ++ cnt;
        id[cnt] = u;
        if(son[u]) dfs2(son[u] , f);
        for(Edge *i = Ire[u] ; i ; i = i -> nxt){
            int v = i -> to;
            if(!dfn[v]) dfs2(v , v);
        }
    }

    struct node{
        node *ch[2];
        static queue<node*> q;
        int l , r;
        int val;
        node(int l = 0 , int r = 0 , int val = 0): l(l) , r(r) , val(val){
            ch[0] = ch[1] = NULL;
        }
        inline void up(){
            val = ch[0] -> val + ch[1] -> val;
        }
        inline int mid(){
            return (l + r) >> 1;
        }
        void *operator new(size_t){
            static node *S = NULL , *T = NULL; node *tmp;
            return q.empty() ? (S == T && (T = (S = new node[1024]) + 1024 , S == T) ? NULL : S ++): (tmp = q.front() , q.pop() ,tmp);
        }
        void operator delete(void *qaq){ q.push(static_cast<node*>(qaq)); } 
    }*root;

    queue<node*> node::q;

    inline void build(node *&o , int l , int r){
#ifdef AME__DEBUG
        cerr << l << ' ' << r << '\n';
#endif
        o = new node(l , r);
        if(l == r){
            o -> val = val[id[l]];
            return;
        }
        build(o -> ch[0] , l , o -> mid()); build(o -> ch[1] , o -> mid() + 1 , r);
        o -> up();
    }

    inline int ask(node *o , int l , int r){
        if(l <= o -> l && o -> r <= r){
            return o -> val;
        }
        int res = 0;
        if(l <= o -> mid()){
            res = res + ask(o -> ch[0] , l , r);
        }
        if(r > o -> mid()){
            res = res + ask(o -> ch[1] , l , r);
        }
        return res;
    }

    inline int lca(int x , int y){
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x , y);
            x = fa[top[x]];
        }
        if(dep[x] < dep[y]) swap(x , y);
        return y;
    }

    inline int dist(int x , int y){
        int res = 0;
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) swap(x , y);
            res = res + ask(root , dfn[top[x]] , dfn[x]);
            x = fa[top[x]];
        }
        if(dep[x] < dep[y]) swap(x , y);
        res = res + ask(root , dfn[y] + 1 , dfn[x]);
        return res;
    }

    inline int ask_kth(int x , int k){
        while(dfn[x] - dfn[top[x]] < k){
            k -= (dep[x] - dep[top[x]] + 1);
            x = fa[top[x]];
        }
        return id[dfn[x] - k];
    }

    inline void clear1(){
        Ire.clear(); cnt = 0;
        memset(top , 0 , sizeof top);
        memset(son , 0 , sizeof son);
        memset(dfn , 0 , sizeof dfn);
    }

    inline void clear2(){ delete root; }

    inline void build(int n){
        dfs1(1 , 0); dfs2(1 , 1);
        build(root , 1 , n);
    }
}

inline int Ame_(){
#ifdef AME__
    freopen(".in" , "r" , stdin); freopen(".out" , "w" , stdout); int nol_cl = clock();
#endif
    mian(t);
    for(; t --> 0 ;){
        mian(n); yuni::clear1(); 
        for(int i = 1;i < n;i ++){
            mian(x) , mian(y) , mian(z);
            yuni::Ire.add(x , y , z);
            yuni::Ire.add(y , x , z);
        }
        yuni::build(n);
        while(qwq){
            mians(opt);
            if(opt[0] == 'K'){ 
                mian(x) , mian(y) , mian(k); 
                int dis = yuni::dist(x , y); int lca = yuni::lca(x , y); k = k - 1;
                yuni::dist(x , lca) < k ? printf("%d\n" , yuni::ask_kth(y , dis - k)) : printf("%d\n" , yuni::ask_kth(x , k));
            }
            if(opt[0] == 'D'){
                if(opt[1] == 'I') mian(x) , mian(y) , printf("%d\n" , yuni::dist(x , y));
                if(opt[1] == 'O') break;
            }
        }
        yuni::clear2(); 
    }
#ifdef AME__TIME
    LOG("Time: %dms\n", int((clock() - nol_cl) / (qwq)CLOCKS_PER_SEC * 1000));
#endif
    return ~~(0^_^0);
}
    
int Ame__ = Ame_();
    
int main(){;}

/*
2
6
1 2 1
2 4 1
2 5 2
1 3 1
3 6 2
DIST 4 6
KTH 4 6 4
DONE
6
1 2 1
2 4 1
2 5 2
1 3 1
3 6 2
DIST 4 6
KTH 4 6 4
DONE
*/
2020/10/17 09:16
加载中...