• 洛谷 2590 树的统计


    这个题主要是一些线段树和树剖的基本操作,这里不再赘述(反正大家都会)

    不过还是提几个小细节:

    1. 注意点的树上编号和新编号的转换和使用(特别是单点修改时)。

    2. 点权有负数,maxans的最小值要赋到-30001。

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int MAXN = 500030;
    
    int n, cnt, nid;
    int f[MAXN];
    int top[MAXN];
    int son[MAXN];
    int lid[MAXN];
    int dep[MAXN];
    int siz[MAXN];
    int val[MAXN];
    int nva[MAXN];
    int faz[MAXN];
    
    string s;
    
    int read()
    {
        int x = 0;
        int k = 1;
        char c = getchar();
        
        while (!isdigit(c))
            if (c == '-') k = -1, c = getchar();
            else c = getchar();
        while (isdigit(c))
            x = (x << 3) + (x << 1) + (c ^ 48),
            c = getchar();
        
        return k * x;
    }
    
    struct edge
    {
        int w;
        int u;
        int v;
        int next;
    }e[MAXN<<1];
    
    void addedge(int x, int y)
    {
        ++cnt;
        e[cnt].u = x;
        e[cnt].v = y;
        e[cnt].next = f[x];
        f[x] = cnt;
    }
    
    void dfs1(int u, int father, int depth)
    {
        dep[u] = depth;
        faz[u] = father;
        siz[u] = 1;
        
        for (int i = f[u]; i != -1; i = e[i].next)
        {
            int to = e[i].v;
            if (to == father) continue;
            dfs1(to, u, depth + 1);
            siz[u] += siz[to];
            if (siz[to] > siz[son[u]] || son[u] == -1) son[u] = to;
        } 
    } 
    
    void dfs2(int u, int h)
    {
        ++nid;
        lid[u] = nid;
        nva[nid] = val[u];
        top[u] = h;
        
        if (son[u] == -1) return;
        
        dfs2(son[u], h);
        
        for (int i = f[u]; i != -1; i = e[i].next)
        {
            int to = e[i].v;
            if (!lid[to]) dfs2(to, to);
        } 
    }
    
    // Segmenttree
    
    #define ls u << 1
    #define rs u << 1 | 1
    
    struct segtree
    {
        int l;
        int r;
        int w;
        int b;
        int siz;
    }t[MAXN << 2];
    
    void update(int u)
    {
        t[u].w = t[ls].w + t[rs].w;
        t[u].b = max(t[ls].b, t[rs].b);
    }
    
    void build(int u, int l, int r)
    {
        t[u].l = l;
        t[u].r = r;
        t[u].siz = r - l + 1;
        if (l == r) 
        {
            t[u].w = nva[l];
            t[u].b = nva[l];
            return; 
        }
        int mid = (l + r) >> 1;
        build(ls, l, mid);
        build(rs, mid + 1, r);
        update(u);
    }
    
    void change(int u, int ll, int c)
    {
        if (t[u].l == t[u].r && t[u].l == ll)
        {
            t[u].w = c; 
            t[u].b = c;
            return;
        }
        int mid = (t[u].l + t[u].r) >> 1;
        if (ll <= mid) change(ls, ll, c);
        if (ll > mid) change(rs, ll, c);
        update(u);
    }
    
    int max_(int u, int l, int r)
    {
        if (t[u].l >= l && t[u].r <= r)
            return t[u].b;
        int mid = (t[u].l + t[u].r) >> 1;
        int ans = -1000000000;
        if (l <= mid) ans = max(ans, max_(ls, l, r));
        if (r > mid) ans = max(ans, max_(rs, l, r));
        return ans;
    }
    
    int sum_(int u, int l, int r)
    {
        if (t[u].l >= l && t[u].r <= r)
            return t[u].w;
        int mid = (t[u].l + t[u].r) >> 1;
        int ans = 0;
        if (l <= mid) ans += sum_(ls, l, r);
        if (r > mid) ans += sum_(rs, l, r);
        return ans; 
    }
    
    //sparate
    
    int tsum_(int x, int y)
    {
        int ans = 0;
        while (top[x] != top[y])
        {
            if (dep[top[x]] < dep[top[y]]) swap(x, y);
            ans += sum_(1, lid[top[x]], lid[x]);
            x = faz[top[x]];
        } 
        if (dep[x] > dep[y]) swap(x, y);
        ans += sum_(1, lid[x], lid[y]);
        return ans;
    } 
    
    int tmax_(int x, int y)
    {
        int ans = -10000000;
        while (top[x] != top[y])
        {
            if (dep[top[x]] < dep[top[y]]) swap(x, y);
            ans = max(ans, max_(1, lid[top[x]], lid[x]));
            x = faz[top[x]];
        } 
        if (dep[x] > dep[y]) swap(x, y);
        ans = max(ans, max_(1, lid[x], lid[y]));
        return ans;
    }
    
    //main
    
    int main()
    {
        memset(son, -1, sizeof(son));
        memset(f, -1, sizeof(f));
        n = read();
        for (int i = 1; i < n; ++i) 
        {
            int x, y;
            x = read();
            y = read();
            addedge(x, y);
            addedge(y, x);
        }
        for (int i = 1; i <= n; ++i) val[i] = read();
        
        dfs1(1, 0, 1);
        dfs2(1, 1);
        build(1, 1, n);
        
        int q = read();
        while (q--)
        {
            cin >> s;
            int x = read();
            int y = read();
            if (s[1] == 'H')
                change(1, lid[x], y); 
            else if (s[1] == 'S')
                printf("%d
    ", tsum_(x, y));
            else if (s[1] == 'M')
                printf("%d
    ", tmax_(x, y));
        }
        
    }
  • 相关阅读:
    HDU 1025 Constructing Roads In JGShining's Kingdom (DP+二分)
    HDU 1158 Employment Planning
    HDU 2059 龟兔赛跑
    Csharp 简单操作Word模板文件
    Csharp windowform datagridview Clipboard TO EXCEL OR FROM EXCEL DATA 保存datagridview所有數據
    Csharp 讀寫文件內容搜索自動彈出 AutoCompleteMode
    Csharp windowform controls clear
    CSS DIV大图片右上角叠加小图片
    Csharp DataGridView自定义添加DateTimePicker控件日期列
    Csharp 打印Word文件默認打印機或選擇打印機設置代碼
  • 原文地址:https://www.cnblogs.com/yanyiming10243247/p/9704753.html
Copyright © 2020-2023  润新知