• LCA+树状数组 POJ 2763 Housewife Wind


    题目传送门

    题意:两种操作,问u到v的距离,并且u走到了v;把第i条边距离改成w

    分析:根据DFS访问顺序,将树处理成链状的,那么回边处理成负权值,那么LCA加上BIT能够知道u到v的距离,BIT存储每条边的信息,这样第二种操作也能用BIT快速解决

    利用RMQ的写法不知哪里写挫了,改用倍增法

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/10/6 星期二 11:45:03
    * File Name     :POJ_2763.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e5 + 10;
    const int D = 20;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-8;
    struct Edge {
        int v, w, id, nex;
    }edge[N<<1];
    struct BIT  {
        int c[N<<1], NN;
        void init(int n) {
            NN = n * 2;
            memset (c, 0, sizeof (c));
        }
        void updata(int i, int x)   {
            while (i <= NN) {
                c[i] += x;  i += i & (-i);
            }
        }
        int query(int i)    {
            int ret = 0;
            while (i)   {
                ret += c[i];    i -= i & (-i);
            }
            return ret;
        }
    }bit;
    int head[N];
    int dep[N], rt[D][N], id[N], in[N], out[N];
    int cost[N];
    int e, tim;
    
    void init(void) {
        memset (head, -1, sizeof (head));
        e = 0;
    }
    
    void add_edge(int u, int v, int w, int id)  {
        edge[e] = (Edge) {v, w, id, head[u]};
        head[u] = e++;
    }
    
    void DFS(int u, int fa, int d) {
        dep[u] = d; rt[0][u] = fa;
        for (int i=head[u]; ~i; i=edge[i].nex)  {
            Edge &e = edge[i];
            if (e.v == fa)  continue;
            in[e.id] = id[e.v] = ++tim;
            DFS (e.v, u, d + 1);
            out[e.id] = ++tim;
        }
    }
    
    int LCA(int u, int v)   {
        if (dep[u] < dep[v])    {
            swap (u, v);
        }
        for (int i=0; i<D; ++i) {
            if ((dep[u] - dep[v]) >> i & 1) {
                u = rt[i][u];
            }
        }
        if (u == v) return u;
        for (int i=D-1; i>=0; --i)  {
            if (rt[i][u] != rt[i][v])   {
                u = rt[i][u];
                v = rt[i][v];
            }
        }
        return rt[0][u];
    }
    
    int main(void)    {
        int n, q, s;
        while (scanf ("%d%d%d", &n, &q, &s) == 3)   {
            init ();
            for (int u, v, w, i=1; i<n; ++i)    {
                scanf ("%d%d%d", &u, &v, &cost[i]);
                add_edge (u, v, cost[i], i);
                add_edge (v, u, cost[i], i);
            }
            tim = 0;
            DFS (1, -1, 0);
            for (int i=1; i<D; ++i) {
                for (int j=1; j<=n; ++j)    {
                    rt[i][j] = rt[i-1][j] == -1 ? -1 : rt[i-1][rt[i-1][j]];
                }
            }
    
            bit.init (n);
            for (int i=1; i<n; ++i) {
                bit.updata (in[i], cost[i]);        //入边序号
                bit.updata (out[i], -cost[i]);      //回边序号
            }
    
            int u = s;
            for (int op, i=1; i<=q; ++i)    {
                scanf ("%d", &op);
                if (op == 0)    {
                    int v;  scanf ("%d", &v);               //入点序号和回点序号
                    printf ("%d
    ", bit.query (id[u]) + bit.query (id[v]) - bit.query (id[LCA (u, v)]) * 2);
                    u = v;
                }
                else    {
                    int p, w;   scanf ("%d%d", &p, &w);
                    bit.updata (in[p], w - cost[p]);
                    bit.updata (out[p], cost[p] - w);
                    cost[p] = w;
                }
            }
        }   
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    盲签名——典型的数字签名技术
    环签名——典型的数字签名技术
    多重签名——典型的数字签名技术
    历史多数攻击——共识攻击介绍
    看一篇,学一篇,今日份的pandas,你该这么学!No.2
    哈希算法
    什么是多重签名?多重签名的概念
    POJ 1023 The Fun Number System
    (四)Spring Boot之配置文件-多环境配置
    (四)Spring Boot之配置文件-多环境配置
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4857340.html
Copyright © 2020-2023  润新知