Jiu Yuan Wants to Eat(树链剖分+线段树延迟标记)
Jiu Yuan Wants to Eat
https://nanti.jisuanke.com/t/31714
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 nn nodes, each node ii contains weight a[i]a[i], the initial value of a[i]a[i] is 00. The root number of the tree is 11. Now you need to do the following operations:
1)1) Multiply all weight on the path from uu to vv by xx
2)2) For all weight on the path from uu to vv, increasing xx to them
3)3) For all weight on the path from uu to vv, change them to the bitwise NOT of them
4)4) Ask the sum of the weight on the path from uu to vv
The answer modulo 2^{64}264.
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\backsim\backsim\backsim∽∽∽
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 00 become 11, and those that are 11 become 00. For example:
NOT 0111 (decimal 7) = 1000 (decimal 8)
NOT 10101011 = 01010100
Input
The input contains multiple groups of data.
For each group of data, the first line contains a number of nn, and the number of nodes.
The second line contains (n - 1)(n−1) integers b_ibi, which means that the father node of node (i +1)(i+1) is b_ibi.
The third line contains one integer mm, which means the number of operations,
The next mm lines contain the following four operations:
At first, we input one integer opt
1)1) If opt is 11, then input 33 integers, u, v, xu,v,x, which means multiply all weight on the path from uu to vv by xx
2)2) If opt is 22, then input 33 integers, u, v, xu,v,x, which means for all weight on the path from uu to vv, increasing xx to them
3)3) If opt is 33, then input 22 integers, u, vu,v, which means for all weight on the path from uu to vv, change them to the bitwise NOT of them
4)4) If opt is 44, then input 22 integers, u, vu,v, and ask the sum of the weights on the path from uu to vv
1 \le n,m,u,v \le 10^51≤n,m,u,v≤105
1 \le x < 2^{64}1≤x<264
Output
For each operation 44, 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<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
#define maxn 100005
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
typedef unsigned long long ull;
using namespace std; ull tree[maxn<<],lazya[maxn<<],lazym[maxn<<];
int n;
ull v[maxn],val[maxn];
int dep[maxn],fa[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],cnt;
vector<ull>ve[maxn]; void pushup(int rt){
tree[rt]=tree[rt<<]+tree[rt<<|];
} void pushdown(int len,int rt){
if(lazya[rt]||lazym[rt]!=){
lazym[rt<<]*=lazym[rt];
lazym[rt<<|]*=lazym[rt];
lazya[rt<<]*=lazym[rt];
lazya[rt<<|]*=lazym[rt];
lazya[rt<<]+=lazya[rt];
lazya[rt<<|]+=lazya[rt];
tree[rt<<]*=lazym[rt];
tree[rt<<|]*=lazym[rt];
tree[rt<<]+=(len-len/)*lazya[rt];
tree[rt<<|]+=len/*lazya[rt];
lazya[rt]=;
lazym[rt]=;
}
} void build(int l,int r,int rt){
lazya[rt]=;
lazym[rt]=;
if(l==r){
tree[rt]=;
return;
}
int mid=(l+r)/;
build(lson);
build(rson);
pushup(rt);
} void mul(int L,int R,ull k,int l,int r,int rt){
if(L<=l&&R>=r){
pushdown(r-l+,rt);
tree[rt]*=k;
lazym[rt]*=k;
lazya[rt]*=k;
return;
}
int mid=(l+r)/;
pushdown(r-l+,rt);
if(L<=mid) mul(L,R,k,lson);
if(R>mid) mul(L,R,k,rson);
pushup(rt);
} void add(int L,int R,ull k,int l,int r,int rt){
if(L<=l&&R>=r){
pushdown(r-l+,rt);
tree[rt]+=(r-l+)*k;
lazya[rt]+=k;
return;
}
int mid=(l+r)/;
pushdown(r-l+,rt);
if(L<=mid) add(L,R,k,lson);
if(R>mid) add(L,R,k,rson);
pushup(rt);
} void Not(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
pushdown(r-l+,rt);
tree[rt]+=(r-l+);
tree[rt]=-tree[rt];
lazym[rt]=-lazym[rt];
lazya[rt]++;
lazya[rt]=-lazya[rt];
return;
}
int mid=(l+r)/;
pushdown(r-l+,rt);
if(L<=mid) Not(L,R,lson);
if(R>mid) Not(L,R,rson);
pushup(rt);
} ull query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
return tree[rt];
}
int mid=(l+r)/;
pushdown(r-l+,rt);
ull ans=;
if(L<=mid) ans+=query(L,R,lson);
if(R>mid) ans+=query(L,R,rson);
pushup(rt);
return ans;
} void dfs1(int now,int f,int deep){
dep[now]=deep;
siz[now]=;
fa[now]=f;
int maxson=-;
for(int i=;i<ve[now].size();i++){
if(ve[now][i]==f) continue;
dfs1(ve[now][i],now,deep+);
siz[now]+=siz[ve[now][i]];
if(siz[ve[now][i]]>maxson){
maxson=siz[ve[now][i]];
son[now]=ve[now][i];
}
}
} void dfs2(int now,int topp){
id[now]=++cnt;
val[cnt]=v[now];
top[now]=topp;
if(!son[now]) return;
dfs2(son[now],topp);
for(int i=;i<ve[now].size();i++){
if(ve[now][i]==son[now]||ve[now][i]==fa[now]) continue;
dfs2(ve[now][i],ve[now][i]);
}
} ull qRange(int x,int y){
ull ans=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=query(id[top[x]],id[x],,n,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(id[x],id[y],,n,);
return ans;
} void addRange(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(id[top[x]],id[x],k,,n,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(id[x],id[y],k,,n,);
} void mulRange(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
mul(id[top[x]],id[x],k,,n,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
mul(id[x],id[y],k,,n,);
} void notRange(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Not(id[top[x]],id[x],,n,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
Not(id[x],id[y],,n,);
} int main(){
int m,r;
while(~scanf("%d",&n)){
memset(v,,sizeof(v));
memset(val,,sizeof(val));
memset(dep,,sizeof(dep));
memset(fa,,sizeof(fa));
memset(siz,,sizeof(siz));
memset(son,,sizeof(son));
memset(id,,sizeof(id));
memset(top,,sizeof(top));
int pos,z,x,y;
for(int i=;i<=n;i++){
ve[i].clear();
}
for(int i=;i<=n;i++){
scanf("%d",&x);
ve[x].push_back(i);
ve[i].push_back(x);
}
cnt=;
dfs1(,,);
dfs2(,);
build(,n,);
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d %d %d",&pos,&x,&y);
if(pos==){
scanf("%d",&z);
mulRange(x,y,z);
}
else if(pos==){
scanf("%d",&z);
addRange(x,y,z);
}
else if(pos==){
notRange(x,y);
}
else{
printf("%llu\n",qRange(x,y));
}
}
}
}
Jiu Yuan Wants to Eat(树链剖分+线段树延迟标记)的更多相关文章
- ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat (树链剖分+线段树)
题目链接:https://nanti.jisuanke.com/t/31714 题意:给你一棵树,初始全为0,有四种操作: 1.u-v乘x 2.u-v加x 3. u-v取反 4.询问u-v ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- java学习——类之YuanZhu
package hello; import java.util.Scanner; public class YuanZhu { public static void main(String[] arg ...
- 用三个线程按顺序循环打印ABC三个字母
有两种方法:semaphore信号量和mutex互斥锁.需要注意的是C++11已经没有semaphore. C++ 并发编程(六):信号量(Semaphore) - 止于至善 - SegmentFau ...
- python unittest单元测试框架-1
Test Case.Test Suite.Test Runner.Test Fixture Test Case:单个测试用例 Test Suite:测试组合.可以把多个测试用例集合在一起执行. Tes ...
- Linux中的ls命令详细使用
ls命令是linux下最常用的命令之一,ls跟dos下的dir命令是一样的都是用来列出目录下的文件,下面我们就来一起看看ls的用法 英文全名:List即列表的意思,当我们学习某种东西的时候要做到知其所 ...
- git如何查看某个人提交的日志。
我们知道,在git进行cherry-pick的时候,找到commit id是至关重要, 如果我们是很多人在一个分支开发,开发完了之后,发现某个人的功能,需要单独cherry-pick到另外一分支上去. ...
- HttpClient上传下载文件
HttpClient上传下载文件 java HttpClient Maven依赖 <dependency> <groupId>org.apache.httpcomponents ...
- El中调用静态方法
最近在项目中遇到需要调用静态方法的问题,形如: <c:forEach items="beans" var="bean"> <p>总数:$ ...
- 6.15-初识JSP、javaweb
一.javaweb web服务器 tomcat C/S 客户端/服务器 B/S 浏览器/服务器 URL: http协议 https 加密的协议 localhost 127.0.0.1 常用web服务器 ...
- Spark SQL Hive Support Demo
前提: 1.spark1.0的包编译时指定支持hive:./make-distribution.sh --hadoop 2.3.0-cdh5.0.0 --with-yarn --with-hive - ...
- ETL,BPM与ESB三者的一些感悟
1.ETL: 数据层之间,主要在数据库层面上进行数据抽取过程------数据库层 2.ESB 异构系统之间通过总线技术,实现系统交互---------------系统通信层 3.BPM 自动化流程处理 ...