zoukankan      html  css  js  c++  java
  • Jiu Yuan Wants to Eat

    问题 E: Jiu Yuan Wants to Eat

    时间限制: 4 Sec  内存限制: 128 MB
    提交: 89  解决: 35
    [提交] [状态] [命题人:admin]

    题目描述

    You ye Jiu yuan is the daughter of the Great GOD Emancipator.  And when she becomes an adult, she will be queen of Tusikur, so she wanted to travel the world while she was still young. In a country, she found a small pub called Whitehouse. Just as she was about to go in for a drink, the boss Carola appeared. And ask her to solve this problem or she will not be allowed to enter the pub. The problem description is as follows:
    There is a tree with n nodes, each node i contains weight a[i], the initial value of a[i] is 0.  The root number of the tree is 1. Now you need to do the following operations:
    1) Multiply all weight on the path from u to v by x
    2) For all weight on the path from u to v, increasing x to them
    3) For all weight on the path from u to v, change them to the bitwise NOT of them
    4) Ask the sum of the weight on the path from u to v
    The answer modulo 2^64.

    Jiu Yuan is a clever girl, but she was not good at algorithm, so she hopes that you can help her solve this problem. Ding~~~

    The bitwise NOT is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0. For example:

    NOT 0111 (decimal 7) = 1000 (decimal 8)
    NOT 10101011 = 01010100

    输入

    The input contains multiple groups of data.
    For each group of data, the first line contains a number of n, and the number of nodes.
    The second line contains (n - 1) integers bi, which means that the father node of node (i +1) is bi.
    The third line contains one integer m, which means the number of operations,
    The next m lines contain the following four operations:
    At first, we input one integer opt
    1) If opt is 1, then input 3 integers, u, v, x, which means multiply all weight on the path from u to v by x
    2) If opt is 2, then input 3 integers, u, v, x, which means for all weight on the path from u to v, increasing x to them
    3) If opt is 3, then input 2 integers, u, v, which means for all weight on the path from u to v, change them to the bitwise NOT of them
    4) If opt is 4, then input 2 integers, u, v, and ask the sum of the weights on the path from u to v

    1 ≤ n, m, u, v ≤ 10^5
    1 ≤ x < 2^64
     

    输出

    For each operation 4, output the answer.

    样例输入

    7
    1 1 1 2 2 4
    5
    2 5 6 1
    1 1 6 2
    4 5 6
    3 5 2
    4 2 2
    2
    1
    4
    3 1 2
    4 1 2
    3 1 1
    4 1 1
    

    样例输出

    5
    18446744073709551613
    18446744073709551614
    0
    

     

    #include <bits/stdc++.h>
    
    #define ll unsigned long long
    using namespace std;
    //typedef long long ll;
    const int maxn = 300600;
    //const ll mod = 1000000007;
    
    const ll mod = 18446744073709551615;
    struct node {
        int to, nx;
    } p[maxn];
    struct segment_tree {
        int l, r;
        ll val, add_tag;
        ll mul_tag;
    } s[maxn];
    int n, q, tot;
    int head[maxn];
    int fa[maxn], dep[maxn];
    int siz[maxn];
    int son[maxn];
    int top[maxn], dfn[maxn], id[maxn];
    
    void add_edge(int u, int v) {
        p[++tot].to = v;
        p[tot].nx = head[u];
        head[u] = tot;
    }
    
    void dfs1(int u) {
        siz[u] = 1;
        for (int i = head[u]; i; i = p[i].nx) {
            int to = p[i].to;
            if (to == fa[u])continue;
            fa[to] = u;
            dep[to] = dep[u] + 1;
            dfs1(to);
            siz[u] += siz[to];
            if (siz[to] > siz[son[u]]) {
                son[u] = to;
            }
        }
    }
    
    void dfs2(int u, int tp) {
        top[u] = tp;
        dfn[u] = ++tot;
        id[tot] = u;
        if (!son[u])return;
        dfs2(son[u], tp);
        for (int i = head[u]; i; i = p[i].nx) {
            int to = p[i].to;
            if (to != fa[u] && to != son[u]) {
                dfs2(to, to);
            }
        }
    }
    
    void push_up(int rt) {
        s[rt].val = s[rt << 1].val + s[rt << 1 | 1].val;
    }
    
    void build(int l, int r, int rt) {
        s[rt].l = l;
        s[rt].r = r;
        s[rt].val = 0;
        s[rt].add_tag = 0;
        s[rt].mul_tag = 1;
        if (l == r)return;
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        push_up(rt);
    }
    
    void pushdown(int rt) {
        if (s[rt].add_tag != 0 || s[rt].mul_tag != 1) {
            s[rt << 1].val *= s[rt].mul_tag;
            s[rt << 1].val += (s[rt].add_tag * (s[rt << 1].r - s[rt<<1].l + 1));
            s[rt << 1].add_tag = s[rt << 1].add_tag * s[rt].mul_tag + s[rt].add_tag;
            s[rt << 1].mul_tag *= s[rt].mul_tag;
            s[rt << 1 | 1].val *= s[rt].mul_tag;
            s[rt << 1 | 1].val += (s[rt].add_tag * (s[rt << 1|1].r - s[rt << 1|1].l + 1));
            s[rt << 1 | 1].add_tag = s[rt << 1 | 1].add_tag * s[rt].mul_tag + s[rt].add_tag;
            s[rt << 1 | 1].mul_tag *= s[rt].mul_tag;
            s[rt].add_tag = 0;
            s[rt].mul_tag = 1;
        }
    }
    
    void upd(int op, int ql, int qr, ll w, int rt) {
        if (ql <= s[rt].l && qr >= s[rt].r) {
            if (op == 1) {
                s[rt].val += w * (s[rt].r - s[rt].l + 1);
                s[rt].add_tag += w;
            } else if (op == 2) {
                s[rt].val *= w;
                s[rt].add_tag *= w;
                s[rt].mul_tag *= w;
            }
            return;
        }
        pushdown(rt);
        if (ql <= s[rt << 1].r) {
            upd(op, ql, qr, w, rt << 1);
        }
        if (qr >= s[rt << 1 | 1].l) {
            upd(op, ql, qr, w, rt << 1 | 1);
        }
        push_up(rt);
    }
    
    void update(int op, int x, int y, ll w) {
        int fx = top[x], fy = top[y];
        while (fx != fy) {
            if (dep[fx] <= dep[fy]) {
                upd(op, dfn[fy], dfn[y], w, 1);
                y = fa[fy];
                fy = top[y];
            } else {
                upd(op, dfn[fx], dfn[x], w, 1);
                x = fa[fx];
                fx = top[x];
            }
        }
        if (dep[x] <= dep[y]) {
            upd(op, dfn[x], dfn[y], w, 1);
        } else {
            upd(op, dfn[y], dfn[x], w, 1);
        }
    }
    
    ll Query(int ql, int qr, int rt) {
        if (ql <= s[rt].l && qr >= s[rt].r) {
            return s[rt].val;
        }
        pushdown(rt);
        ll ans = 0;
        if (ql <= s[rt << 1].r) {
            ans += Query(ql, qr, rt << 1);
        }
        if (qr >= s[rt << 1 | 1].l) {
            ans += Query(ql, qr, rt << 1 | 1);
        }
        return ans;
    }
    
    ll query(int x, int y) {
        int fx = top[x], fy = top[y];
        ll ans = 0;
        while (fx != fy) {
            if (dep[fx] <= dep[fy]) {
                ans += Query(dfn[fy], dfn[y], 1);
                y = fa[fy];
                fy = top[y];
            } else {
                ans += Query(dfn[fx], dfn[x], 1);
                x = fa[fx];
                fx = top[x];
            }
        }
        if (dep[x] <= dep[y]) {
            ans += Query(dfn[x], dfn[y], 1);
        } else {
            ans += Query(dfn[y], dfn[x], 1);
        }
        return ans;
    }
    
    int main() {
        //freopen("1.txt", "r", stdin);
        while (~scanf("%d", &n)) {
            memset(head, 0, sizeof(head));
            tot = 0;
            memset(top, 0, sizeof(top));
            memset(id, 0, sizeof(id));
            memset(son,0,sizeof(son));
            memset(dep,0,sizeof(dep));
            for (int i = 2, u; i <= n; ++i) {
                scanf("%d", &u);
                add_edge(i, u);
                add_edge(u, i);
            }
            fa[1] = 0;
            dep[1] = 1;
            dfs1(1);
            tot = 0;
            dfs2(1, 1);
    
            build(1, n, 1);
    
            scanf("%d", &q);
            int op, u, v;
            ll x;
    //        for(int i=1;i<=n;++i)printf("%d ",top[i]);
    //        cout<<endl;
    //        for(int i=1;i<=n;++i)printf("%d ",dep[i]);
    //        cout<<endl;
    //        for(int i=1;i<=n;++i)printf("%d ",dfn[i]);
    //        cout<<endl;
            while (q--) {
                scanf("%d", &op);
                if (op == 1) {
                    scanf("%d%d%llu", &u, &v, &x);
    
                    update(2, u, v, x);
    
                } else if (op == 2) {
                    scanf("%d%d%llu", &u, &v, &x);
                    //cout<<"&*"<<endl;
                    update(1, u, v, x);
                    //cout<<"debug op="<<op<<endl;
                } else if (op == 3) {
                    scanf("%d%d", &u, &v);
                    //cout<<"&*"<<endl;
                    update(2, u, v, -1);
                    update(1, u, v, mod);
                    //cout<<"last&*"<<endl;
                } else {
                    scanf("%d%d", &u, &v);
                    printf("%llu
    ", query(u, v));
                }
            }
        }
        return 0;
    }
    /*
    1
    5 3 -3
    -1 -2 3 -4 -5
    -+*
    */
  • 相关阅读:
    Centos7安装go.10.1环境
    centos7安装PHP5
    Linux 无文件攻击memfd_create()具体操作步骤
    centos7 '/mnt/hgfs'下共享文件夹不显示问题
    fiddler连接代理手机无法上网问题解决办法
    centos 镜像软件安装包版本低,手动安装过程
    0 upgraded, 0 newly installed, 0 to remove and 112 not upgraded解决方法
    JavaScript高级程序设计(第3版)第七章读书笔记
    JavaScript高级程序设计(第3版)第六章读书笔记
    JavaScript高级程序设计(第3版)第五章读书笔记
  • 原文地址:https://www.cnblogs.com/czy-power/p/11297334.html
Copyright © 2011-2022 走看看