2018焦作网络赛-E- Jiu Yuan Wants to Eat

题目描述

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

题意
给一棵n个节点的有根树,每个节点有权值,初始是0,m次操作
1 u v x:给u v路径上的点权值*x
2 u v x:给u v路径上的点权值+x
3 u v:给u v路径上的点权值取反
4 u v:询问u v路径上的权值和,对2^64取模

树链剖分:https://wenku.baidu.com/view/a088de01eff9aef8941e06c3.html

然后如果没有取反操作,线段树维护和sum,加法标记add和乘法标记mul即可
对于取反操作,因为是对2^64取模的,即x+(!x)=2^64-1,所以x=(2^64-1)-x,因此取反就变成乘法和加法了:!x=(-1)*x+(-1) (-1对于2^64取模后是(2^64-1))
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N=1e5+100;
int n,m,tot,cnt;
int fa[N],last[N];
int son[N],deep[N],dfn[N],num[N],top[N];//重儿子 深度 dfs序 子树规模 所在重链的顶端节点
ull sum[N*4],add[N*4],mul[N*4];
struct orz{
    int v,nex;}e[N];
void init()
{
    cnt=0;
    tot=0;
    memset(last,0,sizeof(last));
    memset(son,-1,sizeof(son));
}
void Inses(int x,int y)
{
    cnt++;
    e[cnt].v=y;
    e[cnt].nex=last[x];
    last[x]=cnt;
}
void dfs1(int x,int d)
{
    deep[x]=d;
    num[x]=1;
    for (int i=last[x];i;i=e[i].nex)
    {
        int v=e[i].v;
        dfs1(v,d+1);
        num[x]+=num[v];
        if (son[x]==-1 || num[v]>num[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int sp)
{
    top[x]=sp;
    dfn[x]=++tot;
    if (son[x]==-1) return ;
    dfs2(son[x],sp);
    for (int i=last[x];i;i=e[i].nex)
    {
        int v=e[i].v;
        if (v!=son[x]) dfs2(v,v);
    }
}
void PushUp(int s)
{
    sum[s]=sum[s<<1]+sum[s<<1|1];
}
void PushDown(int s,int l,int r)
{
    if (mul[s]!=1)
    {
        mul[s<<1]*=mul[s];
        mul[s<<1|1]*=mul[s];
        add[s<<1]*=mul[s];
        add[s<<1|1]*=mul[s];
        sum[s<<1]*=mul[s];
        sum[s<<1|1]*=mul[s];
        mul[s]=1;
    }
 
    if (add[s])
    {
        add[s<<1]+=add[s];
        add[s<<1|1]+=add[s];
        int mid=(l+r)>>1;
        sum[s<<1]+=(ull)(mid-l+1)*add[s];
        sum[s<<1|1]+=(ull)(r-mid)*add[s];
        add[s]=0;
    }
}
 
void build(int s,int l,int r)
{
    sum[s]=add[s]=0;
    mul[s]=1;
    if (l==r) return ;
    int m=(l+r)>>1;
    build(s<<1,l,m); build(s<<1|1,m+1,r);
    PushUp(s);
}
void update(int s,int l,int r,int L,int R,ull val,int op)
{
    //printf("s=%d,l=%d,r=%d,L=%d,R=%d\n",s,l,r,L,R);
    if (L<=l&&r<=R)
    {
        if (l!=r) PushDown(s,l,r);
        if (op==1)
        {
            mul[s]*=val;
            add[s]*=val;
            sum[s]*=val;
        }
        else if (op==2)
        {
            add[s]+=val;
            sum[s]+=(ull)(r-l+1)*val;
        }
        else
        {
            mul[s]*=val;
            add[s]*=val;
            add[s]+=val;
            sum[s]=(ull)(r-l+1)*val-sum[s];
        }
        return;
    }
    PushDown(s,l,r);
    int mid=(l+r)>>1;
    if (L<=mid) update(s<<1,l,mid,L,R,val,op);
    if (R>mid) update(s<<1|1,mid+1,r,L,R,val,op);
    PushUp(s);
}
ull query(int s,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return sum[s];
    PushDown(s,l,r);
    int mid=(l+r)>>1;
    ull ans=0;
    if (L<=mid) ans+=query(s<<1,l,mid,L,R);
    if (R>mid) ans+=query(s<<1|1,mid+1,r,L,R);
    PushUp(s);
    return ans;
}
void solve(int op,int x, int y,ull val)
{
    if (op==3) val=-1;
    if (op<=3)
    {
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x, y);
            update(1,1,n,dfn[top[x]],dfn[x],val,op);
            x=fa[top[x]];
        }
        if (deep[x]>deep[y]) swap(x,y);
        update(1,1,n,dfn[x],dfn[y],val,op);
    }
    else
    {
        ull ans=0;
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x, y);
            ans+=query(1,1,n,dfn[top[x]],dfn[x]);
            x=fa[top[x]];
        }
        if (deep[x]>deep[y]) swap(x,y);
        ans+=query(1,1,n,dfn[x],dfn[y]);
        printf("%llu\n",ans);
    }
}
 
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        init();
        for (int i=2;i<=n;i++)
        {
            scanf("%d",&fa[i]);
            Inses(fa[i],i);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        scanf("%d",&m);
        int op,u,v; ull x;
        while (m--)
        {
            scanf("%d",&op);
            if (op==1 || op==2) scanf("%d%d%llu",&u,&v,&x);
            else scanf("%d%d",&u,&v);
            solve(op,u,v,x);
        }
    }
    return 0;
}
View Code
 

转载于:https://www.cnblogs.com/tetew/p/11293766.html

`vxe-table` 是 Vue 企业级 UI 组件库 Vuetify 组件套件的增强版,它提供了丰富的表格组件功能,包括但不限于树形数据的支持。在使用 `vxe-table` 处理树形数据时,尾部插入(即新增行并将其作为树的末梢节点)可以通过以下步骤实现: 1. 首先,确保你在 `vxe-table` 中配置了支持树形结构的数据,比如 `tree-props` 属性用于指定哪些字段是树结构的标识,如 `parent` 或 `level`。 ```html <vxe-table :tree-props="{ children: 'children', parent: 'parent'}" :data="treeData"> <!-- ... --> </vxe-table> ``` 2. 定义你的树形数据结构,每条数据项都有一个 `parent` 字段引用其父节点,以及一个 `children` 数组存放其子节点。 ```js data() { return { treeData: [ { id: 1, name: '父节点1', parent: null }, { id: 2, name: '子节点1', parent: 1 }, // 更多节点... ], newTreeNode: {} // 新增的节点初始值 }; } ``` 3. 创建一个方法用于在树的尾部添加新节点。你可以遍历当前树的最后一层,找到它的最后一个元素,然后将新的节点追加到该元素的 `children` 数组中。 ```js methods: { appendToLastLevel() { const lastLevel = this.treeData .filter(item => item.parent === null) // 如果是顶级节点 .map(item => item.children) .flat(); if (lastLevel.length > 0) { lastLevel[lastLevel.length - 1].push(this.newTreeNode); } // 更新数据状态 this.$set(this.treeData, this.newTreeNode.parent, this.newTreeNode); this.newTreeNode.parent = null; // 重置新的节点为顶级节点 } } ``` 4. 当你需要在树尾部插入新节点时,调用 `appendToLastLevel` 方法即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值