• Poj3237Tree 树链剖分


    点更新 ,段更新, 段查询。 注意的是 线段树维护区间最大值 ,在反转的时候 不能直接取反,那样就变成了 当时的最小值。

    所以维护两个值,一个最小值 一个最大值 ,在进行反转操作的时候,取反并且交换两个值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<stdlib.h>
    using namespace std;
    typedef long long LL;
    const int maxn = 22222;
    struct Node
    {
        int next; int to;
    }e[maxn * 2];
    int edge[maxn][10];
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    int len; int z;
    int size[maxn]; int son[maxn]; int deep[maxn], father[maxn];
    int color[maxn << 2];
    int sum[maxn << 2];
    int head[maxn];
    int pos[maxn]; int top[maxn];
    const int INF = 1 << 30;
    int sum1[maxn << 2];
    
    void add(int from, int to)
    {
        e[len].to = to;
        e[len].next = head[from];
        head[from] = len++;
    }
    
    void init(int x)
    {
        size[x] = 1; son[x] = 0;
        for (int i = head[x]; i != -1; i = e[i].next){
            int cc = e[i].to;
            if (cc == father[x]) continue;
            father[cc] = x; deep[cc] = deep[x] + 1;
            init(cc);
            size[x] += size[cc];
            if (size[son[x]] < size[cc]) son[x] = cc;
        }
    }
    
    void dfs(int x, int tp)
    {
        pos[x] = ++z; top[x] = tp;
        if (son[x]) dfs(son[x], tp);
        for (int i = head[x]; i != -1; i = e[i].next){
            int cc = e[i].to;
            if (cc == father[x] || cc == son[x]) continue;
            dfs(cc, cc);
        }
    }
    
    void build(int l, int r, int rt)
    {
        sum[rt] = -INF; sum1[rt] = INF;
        color[rt] = 0;
        if (l == r) return;
        int mid = (l + r) >> 1;
        build(lson); build(rson);
    }
    
    void down(int rt)
    {
        if (color[rt]){
            sum[rt << 1] = -sum[rt << 1]; sum[rt << 1 | 1] = -sum[rt << 1 | 1]; sum1[rt << 1] = -sum1[rt << 1]; sum1[rt << 1 | 1] = -sum1[rt << 1 | 1];
            swap(sum[rt << 1], sum1[rt << 1]); swap(sum[rt << 1 | 1], sum1[rt << 1 | 1]);
            color[rt << 1] ^= 1; color[rt << 1 | 1] ^= 1;
            color[rt] = 0;
        }
    }
    
    void up(int rt)
    {
        sum[rt] = max(sum[rt << 1], sum[rt << 1 | 1]);
        sum1[rt] = min(sum1[rt << 1], sum1[rt << 1 | 1]);
    }
    
    void update(int L, int R, int l, int r, int rt)
    {
        if (L <= l&&r <= R) {
            color[rt] ^= 1; sum[rt] = -sum[rt]; sum1[rt] = -sum1[rt]; swap(sum[rt], sum1[rt]);
            return;
        }
        int mid = (l + r) >> 1;
        down(rt);
        if (L <= mid) update(L, R, lson);
        if (R > mid) update(L, R, rson);
        up(rt);
    }
    
    void update1(int key, int ans, int l, int r, int rt)
    {
        if (l == r){
            sum1[rt] = ans;
            sum[rt] = ans; return;
        }
        down(rt);
        int mid = (l + r) >> 1;
        if (key <= mid) update1(key, ans, lson);
        else update1(key, ans, rson);
        up(rt);
    }
    
    int ask(int L, int R, int l, int r, int rt)
    {
        if (L <= l&&r <= R) return sum[rt];
        down(rt);
        int mid = (l + r) >> 1;
        int Max = -INF;
        if (L <= mid) Max = max(Max, ask(L, R, lson));
        if (R > mid) Max = max(Max, ask(L, R, rson));
        return Max;
    }
    
    int gao(int x, int y)
    {
        int Max = -INF;
        int fx = top[x]; int fy = top[y];
        while (fx != fy){
            if (deep[fx] < deep[fy]){
                swap(x, y); swap(fx, fy);
            }
            Max = max(Max, ask(pos[fx], pos[x], 1, z, 1));
            x = father[fx]; fx = top[x];
        }
        if (x == y) return Max;
        if (deep[x]>deep[y])swap(x, y);
        Max = max(Max, ask(pos[son[x]], pos[y], 1, z, 1));
        return Max;
    
    }
    
    void gao1(int x, int y)
    {
        int fx = top[x]; int fy = top[y];
        while (fx != fy){
            if (deep[fx]<deep[fy]) swap(x, y), swap(fx, fy);
            update(pos[fx], pos[x], 1, z, 1);
            x = father[fx];  fx = top[x];
        }
        if (x == y) return;
        if (deep[x]>deep[y]) swap(x, y);
        update(pos[son[x]], pos[y], 1, z, 1);
    }
    
    
    int main()
    {
        // freopen("input.txt","r",stdin);
        //freopen("output.txt","w",stdout);
        int t;
        scanf("%d", &t);
        int n, a, b;
        char str[1000];
        while (t--){
            scanf("%d", &n);
            len = 0; z = 0;
            memset(head, -1, sizeof(head));
            deep[1] = 1;
            for (int i = 1; i < n; i++){
                scanf("%d%d%d", &edge[i][0], &edge[i][1], &edge[i][2]);
                add(edge[i][0], edge[i][1]);
                add(edge[i][1], edge[i][0]);
            }
            init(1); dfs(1, 1); build(1, z, 1);
            for (int i = 1; i < n; i++){
                int a = edge[i][0]; int b = edge[i][1]; int c = edge[i][2];
                if (deep[a]>deep[b]) swap(edge[i][0], edge[i][1]);
                update1(pos[edge[i][1]], c, 1, z, 1);
            }
            while (scanf("%s", str) != EOF){
                if (str[0] == 'D') break;
                if (str[0] == 'Q'){
                    scanf("%d%d", &a, &b);
                    int t = gao(a, b);
                    printf("%d
    ", t);
                }
                if (str[0] == 'C'){
                    scanf("%d%d", &a, &b);
                    edge[a][2] = b;
                    update1(pos[edge[a][1]], b, 1, z, 1);
                }
                if (str[0] == 'N'){
                    scanf("%d%d", &a, &b);
                    gao1(a, b);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    elasticsearch 索引清理脚本及常用命令
    git 快速入门及常见用法
    第01章-成本,你真的算对过吗?
    windows mysql安装及常用命令
    centos7 systemctl配置开机自启动服务
    python pip手动安装二进制包
    centos7使用nginx+uwsgi部署python django项目
    python json.loads()、json.dumps()和json.dump()、json.load()区别
    比阿里云快2倍的InfluxDB集群,我们开源了
    为什么是InfluxDB | 写在《InfluxDB原理和实战》出版之际
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4076812.html
Copyright © 2020-2023  润新知