• SPOJ QTREE2 lct


    题目链接
    题意:
    给一棵树。有边权
    1、询问路径的边权和
    2、询问沿着路径的第k个点标。
    思路:lct裸题。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <time.h>
    #include <vector>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <stack>
    #include <cstring>
    #include <cmath>
    #include <set>
    #include <vector>
    using namespace std;
    template <class T>
    inline bool rd(T &ret) {
        char c; int sgn;
        if (c = getchar(), c == EOF) return 0;
        while (c != '-' && (c<'0' || c>'9')) c = getchar();
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
    }
    template <class T>
    inline void pt(T x) {
        if (x <0) {
            putchar('-');
            x = -x;
        }
        if (x>9) pt(x / 10);
        putchar(x % 10 + '0');
    }
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 30005;
    const int inf = 10000000;
    struct Node *null;
    struct Node{
        Node *fa, *ch[2];
        int size;
        int val, ma, sum, id;
        bool rev;
        inline void put(){
            printf("%d:id, %d,%d,%d (%d,%d) fa:%d 
    ", id, val, ma, sum, ch[0]->id, ch[1]->id, fa->id);
        }
        void debug(Node *x){
            if (x == null)return;
            x->put();
            if (x->ch[0] != null)putchar('L'), debug(x->ch[0]);
            if (x->ch[1] != null)putchar('r'), debug(x->ch[1]);
        }
    
        inline void clear(int _val, int _id){
            fa = ch[0] = ch[1] = null;
            size = 1;
            rev = 0;
            id = _id;
            val = ma = sum = _val;
        }
        inline void add_val(int _val){
            val += _val;
            sum += _val;
            ma = max(ma, val);
        }
        inline void push_up(){
            size = 1 + ch[0]->size + ch[1]->size;
    
            sum = ma = val;
            if (ch[0] != null) {
                sum += ch[0]->sum; 
                ma = max(ma, ch[0]->ma);
            }
            if (ch[1] != null){
                sum += ch[1]->sum;
                ma = max(ma, ch[1]->ma);
            }
        }
        inline void push_down(){
            if (rev){
                flip(); ch[0]->rev ^= 1; ch[1]->rev ^= 1;
            }
        }
        inline void setc(Node *p, int d){
            ch[d] = p;
            p->fa = this;
        }
        inline bool d(){
            return fa->ch[1] == this;
        }
        inline bool isroot(){
            return fa == null || fa->ch[0] != this && fa->ch[1] != this;
        }
        inline void flip(){
            if (this == null)return;
            swap(ch[0], ch[1]);
            rev ^= 1;
        }
        inline void go(){//从链头開始更新到this
            if (!isroot())fa->go();
            push_down();
        }
        inline void rot(){
            Node *f = fa, *ff = fa->fa;
            int c = d(), cc = fa->d();
            f->setc(ch[!c], c);
            this->setc(f, !c);
            if (ff->ch[cc] == f)ff->setc(this, cc);
            else this->fa = ff;
            f->push_up();
        }
        inline Node*splay(){
            go();
            while (!isroot()){
                if (!fa->isroot())
                    d() == fa->d() ?

    fa->rot() : rot(); rot(); } push_up(); return this; } inline Node* access(){//access后this就是到根的一条splay,而且this已经是这个splay的根了 for (Node *p = this, *q = null; p != null; q = p, p = p->fa){ p->splay()->setc(q, 1); p->push_up(); } return splay(); } inline Node* find_root(){ Node *x; for (x = access(); x->push_down(), x->ch[0] != null; x = x->ch[0]); return x; } void make_root(){ access()->flip(); } void cut(){//把这个点的子树脱离出去 access(); ch[0]->fa = null; ch[0] = null; push_up(); } void cut(Node *x){ if (this == x || find_root() != x->find_root())return; else { x->make_root(); cut(); } } void link(Node *x){ if (find_root() == x->find_root())return; else { make_root(); fa = x; } } }; Node pool[N], *tail; Node *node[N], *ee[N]; int n, q; void debug(Node *x){ if (x == null)return; x->put(); debug(x->ch[0]); debug(x->ch[1]); } inline int ask(Node *x, Node *y){ x->access(); // for (int i = 1; i <= n; i++)debug(node[i]), putchar(' '); for (x = null; y != null; x = y, y = y->fa){ y->splay(); // for (int i = 1; i <= n; i++)debug(node[i]), putchar(' '); if (y->fa == null)return y->ch[1]->sum + x->sum; y->setc(x, 1); y->push_up(); } } inline Node* get_kth(Node *x, int k){ while (x->ch[0]->size + 1 != k){ if (x->ch[0]->size >= k) x = x->ch[0]; else k -= x->ch[0]->size + 1, x = x->ch[1]; } return x; } inline int query_kth(Node *x, Node *y, int k){ x->access(); for (x = null; y != null; x = y, y = y->fa){ y->splay(); if (y->fa == null){ if (k == y->ch[1]->size + 1)return y->id; if (k < y->ch[1]->size + 1)return get_kth(y->ch[1], y->ch[1]->size - k + 1)->id; return get_kth(x, k - y->ch[1]->size - 1)->id; } y->setc(x, 1); y->push_up(); } } struct Edge{ int from, to, dis, id, nex; }edge[N << 1]; int head[N], edgenum; void add(int u, int v, int dis, int id){ Edge E = { u, v, dis, id, head[u] }; edge[edgenum] = E; head[u] = edgenum++; } bool vis[N]; void bfs(){ fill(vis + 1, vis + 1 + n, false); queue<int>q; q.push(1); vis[1] = true; while (!q.empty()){ int u = q.front(); q.pop(); for (int i = head[u]; ~i; i = edge[i].nex){ int v = edge[i].to; if (vis[v])continue; vis[v] = true; q.push(v); ee[edge[i].id] = node[v]; node[v]->val = edge[i].dis; node[v]->push_up(); node[v]->fa = node[u]; } } } int main(){ int T; rd(T); while (T--){ rd(n); fill(head + 1, head + n + 1, -1); edgenum = 0; tail = pool; null = tail++; null->clear(-inf, 0); null->size = 0; null->sum = 0; for (int i = 1; i <= n; i++) { node[i] = tail++; node[i]->clear(0, i); } for (int i = 1, u, v, d; i < n; i++){ rd(u); rd(v); rd(d); add(u, v, d, i); add(v, u, d, i); } bfs(); char str[10]; int u, v, k; while (true){ scanf("%s", str); if (str[1] == 'O')break; rd(u); rd(v); if (str[0] == 'D')pt(ask(node[u], node[v])), putchar(' '); else { rd(k); pt(query_kth(node[u], node[v], k)); putchar(' '); } } puts(""); } return 0; } /* 1 6 1 2 1 2 4 1 2 5 2 1 3 1 3 6 2 DIST 4 6 KTH 4 6 4 KTH 6 5 4 DIST 2 5 */

  • 相关阅读:
    Python 操作Excel之通过xlutils实现在保留原格式的情况下追加写入数据
    【转载】Python字符串操作之字符串分割与组合
    【转】Python判断字符串是否为字母或者数字
    Appium 在测试android混合应用时,关于webview页面切换的那些事儿
    使用pip install XX 命令时报错
    Appium笔记(二) 丶Appium的安装
    Android SDK的下载与安装
    KlayGE 4.4中渲染的改进(五):OpenGL 4.4和OpenGLES 3
    最先进的开源游戏引擎KlayGE 4.4发布
    KlayGE 4.4中渲染的改进(四):SSSSS
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7142139.html
Copyright © 2020-2023  润新知