chain split tree hdu 3966

Tree chain split template title, record it.
Summary:
Here I re several times, that the update operation, should first determine the depth of the head node, jump shallow depth priority, rather than the current two points that determine deeper, it makes no sense.
Here son can memset to -1, because when dfs priority assignment does not exist array bounds.
-1 head array also need to be copied.
The remaining array will be assigned in the order twice dfs, a group of inputs not have to repeat more empty, it will automatically overwrite the previous result.

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
int n, m, p;
int a[N];
struct node { int to, next; }edge[2 * N];
int head[N];
int dep[N], fa[N], siz[N], id[N], neww[N], top[N], son[N], rk[N];
ll tree[N << 2], lazy[N << 2];
int cnt = 0;
int num = 0;
void addedge(int u, int v)
{
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}
void pushup(int root)
{
    tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root, int l, int r)
{
    int lrg = (r - l + 1) - ((r - l + 1) >> 1); int rrg = (r - l + 1) >> 1;
    if (lazy[root])
    {
        lazy[rrt] += lazy[root]; lazy[lrt] += lazy[root];
        tree[lrt] += 1ll * lrg * lazy[root]; tree[rrt] += 1ll * rrg * lazy[root];
        lazy[root] = 0;
    }
}
void build(int l, int r, int root)
{
    lazy[root] = 0;
    if (l == r) { tree[root] = a[rk[l]]; return; }
    int mid = (l + r) >> 1;
    build(lson); build(rson);
    pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int val)
{
    if (lf <= l && r <= rt)
    {
        tree[root] += val * (r - l + 1) * 1ll;
        lazy[root] += val;
        return;
    }
    pushdown(root, l, r);
    int mid = (l + r) >> 1;
    if (lf <= mid)update(lson, lf, rt, val);
    if (rt > mid)update(rson, lf, rt, val);
    pushup(root);
}
ll querry(int l, int r, int root, int pos)
{
    if (l == r)
    {
        return tree[root];
    }
    pushdown(root, l, r);
    int mid = (l + r) >> 1;
    ll ans = 0;
    if (pos <= mid)ans += querry(lson, pos); else ans += querry(rson, pos);
    return ans;
}
void dfs1(int u, int pre, int d) {
    dep[u] = d;
    fa[u] = pre;
    siz[u] = 1;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if (v == pre) continue;
        dfs1(v, u, d + 1);
        siz[u] += siz[v];
        if (son[u] == -1 || siz[v] > siz[son[u]])
            son[u] = v;
    }
}
void dfs2(int u, int tp) {   //得到top
    top[u] = tp;
    id[u] = ++num;
    rk[num] = u;
    if (son[u] == -1) return;
    dfs2(son[u], tp);
    for (int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if (v != son[u] && v != fa[u]) {
            dfs2(v, v);
        }
    }
}
void updaterange(int x, int y, int val)
{
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])swap(x, y);
        update(1, n, 1, id[top[x]], id[x], val);
        //      cout << "x" << x << endl;
        x = fa[top[x]];
    }
    if (dep[x] < dep[y])swap(x, y);
    update(1, n, 1, id[y], id[x], val);
}
ll rgquerry(int x)
{
    return querry(1, n, 1, id[x]);
}
int main()
{
    while (cin >> n >> m >> p) {
        upd(i, 1, n)a[i] = read();
        cnt = num = 0;
        int u, v;
        memset(head, -1, sizeof(head));
        memset(son, -1, sizeof(son));
        upd(i, 1, m)u = read(), v = read(), addedge(u, v), addedge(v, u);
        char s[2];
        dfs1(1, -1, 1);
        dfs2(1, 1);
        build(1, n, 1);
        //  cout << "tree" << tree[1] << endl;
        int c1, c2, k;
        while (p--)
        {
            cin >> s;
            if (s[0] == 'I')
            {
                c1 = read(); c2 = read(); k = read();
                updaterange(c1, c2, k);
                //  cout << "tree" << tree[1] << endl;
            }
            else if (s[0] == 'D')
            {
                c1 = read(), c2 = read(), k = read();
                updaterange(c1, c2, -k);
            }
            else
            {
                c1 = read();
                printf("%lld\n", rgquerry(c1));
            }
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/LORDXX/p/11681234.html