Home » Practice(Hard) » Dynamic Trees and Queries

Problem Code: ANUDTQSubmit

All submissions for this problem are available.

Read problems statements in Mandarin Chineseand Russian.

Given a directed tree with N nodes. You need to process M queries.
Each node has a key and a value, a node is referenced by its key. N nodes havekeys from 0 to N-1.
Root always has the key equal to 0. Queries can be of the following 4 types:

1. Given a key of a node present in the tree, append a child node to it. The new node gets the smallest never-used positive integer as its key. The value of the new node will be given in the input.

2. Given a key of a node(call it A) present in the tree. Add value to the value of all the nodes present in the subtree rooted at A.

3. Given a key of a node(call it A) present in the tree. Remove the subtree rooted at Afrom the tree.

4. Given a key of a node(call it A) present in the tree. Output the sum of values of all the nodes in subtree rooted at A.

Input is encoded:

Keys in M Queries of the input are encoded in the following way:

Let SPECIAL = 0 initially. Whenever a query of the type 4 occurs, SPECIAL is updated to the result of that query.
All the keys given in queries are encoded, in order to decode them you need to add SPECIAL to it.

That is, you are given encoded_key as input, to get key use the formula key =SPECIAL + encoded_key.

Input

First line of input has N, the number of nodes.

Second line has N integers, the values of given N nodes respectively.

Then, N-1 lines follow, each has two integers u, v. which specifies an edge from u to v.

Next line contains a single integer M, the number of queries.

Each query consists of 2 lines, First line has the the type of query, second line is as follows:

For queries 1 and 2, there are two integers, first one represents the key of a node in tree, second one represents the value.

For queries 3 and 4, there is a single integer, which represents the key of a node in tree.

Output

For each query of type 4, output the required answer.

Constraints

  • 1 ≤ N ≤ 10^5
  • 1 ≤ M ≤ 10^5
  • 0 ≤ u < N
  • 0 ≤ v < N, u is not equal to v
  • All the keys in the input are valid
  • If the type of the query is 3, the the key is nonzero.
  • All the rest numbers in the input are in the range [-1000, 1000]

Example

Input:
2
10 20
0 1
4
4
0
1
-30 5
2
-30 1
4
-30

Output:
30
38

Explanation

Query #1

type = 4 encoded_key = 0

Initially SPECIAL = 0

key = encoded_key + SPECIAL = 0

value at 0 + value at 1 = 10 + 20 = 30 is the answer

Now SPECIAL is updated to 30

Query #2

type = 1 encoded_key = -30 value = 5

SPECIAL = 30

key = encoded_key + SPECIAL = -30 + 30 = 0

So we add a child node(with the key = 2) to the node with the key 0, the child node gets the value of 5

EDITS MADE:

Firstly, sorry for the mistake.

Old : Let SPECIAL = 0 initially. Whenever a query of the type 4 occurs, SPECIAL is increased by the result of that query.

New : Let SPECIAL = 0 initially. Whenever a query of the type 4 occurs, SPECIAL is updated to the result of that query.

题意:给出一颗由有向边构成的树,每个节点有编号、权值

操作1:给编号为A的点新增一个权值为val的叶子节点

操作2:给以编号A为根的子树权值全体+val

操作3:删除以编号为A为根的子树

操作4:询问以编号A为根的子树的权值和

碰到子树常用dfs序解决,但这题是动态增删,dfs序难以完成

所以 用splay维护括号序列 来解决子树问题

具体来说就是每加一个点,实际往splay中加一对括号

查找子树时,找到根节点的左右括号,就确定了子树范围

#include<cstdio>
#define lc ch[x][0]
#define rc ch[x][1]
#define N 401001
using namespace std;
int fa[N],ch[N][],l[N],r[N],siz[N],a[N];
int front[N],to[N],next[N],tot,cnt;
long long sum[N],tag[N],key[N],special;
int n,m;
int read()
{
int x=;int f=; char c=getchar();
while(c<''||c>'') { if(c=='-') f=-; c=getchar(); }
while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
return x*f;
}
long long read2()
{
long long x=;int f=; char c=getchar();
while(c<''||c>'') { if(c=='-') f=-; c=getchar(); }
while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
return x*f;
}
struct SPLAY
{
void up(int x)
{
siz[x]=siz[ch[x][]]+siz[ch[x][]]+;
sum[x]=sum[ch[x][]]+sum[ch[x][]]+key[x];
}
void accumu(int x,long long val)
{
key[x]+=val;
sum[x]+=val*siz[x];
tag[x]+=val;
}
void down(int x)
{
if(lc) accumu(lc,tag[x]);
if(rc) accumu(rc,tag[x]);
tag[x]=;
}
bool getson(int x)
{
return ch[fa[x]][]==x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],k=ch[y][]==x;
if(z) ch[z][ch[z][]==y]=x;
fa[x]=z;
ch[y][k]=ch[x][k^]; ch[x][k^]=y;
fa[y]=x; if(ch[y][k]) fa[ch[y][k]]=y;
up(y);
}
void splay(int x,int g=)
{
while(fa[x]!=g)
{
int y=fa[x],z=fa[y];
if(tag[z]) down(z);
if(tag[y]) down(y);
if(tag[x]) down(x);
if(z!=g) rotate(getson(x)==getson(y) ? y : x);
rotate(x);
up(x);
}
}
int find_pre(int y)
{
splay(y);
int x=ch[y][];
while(rc) x=rc;
return x;
}
int find_suf(int y)
{
splay(y);
int x=ch[y][];
while(lc) x=lc;
return x;
}
void insert(int x,int f,int val)
{
int pre=l[f],suf=find_suf(l[f]);
splay(pre); splay(suf,pre);
l[x]=++tot; r[x]=++tot;
ch[suf][]=l[x]; fa[l[x]]=suf;
ch[l[x]][]=r[x]; fa[r[x]]=l[x];
siz[l[x]]=siz[r[x]]=;
sum[l[x]]=key[l[x]]=val;
sum[r[x]]=key[r[x]]=val;
up(l[x]); up(suf); up(pre);
}
void add(int x,int val)
{
int pre=find_pre(l[x]);
int suf=find_suf(r[x]);
splay(pre); splay(suf,pre);
accumu(ch[suf][],val);
up(suf); up(pre);
}
void del(int x)
{
int pre=find_pre(l[x]);
int suf=find_suf(r[x]);
splay(pre); splay(suf,pre);
ch[suf][]=;
up(suf); up(pre);
}
void query(int x)
{
int pre=find_pre(l[x]);
int suf=find_suf(r[x]);
splay(pre);
splay(suf,pre);
special=sum[ch[suf][]]/;
printf("%lld\n",special);
}
}Splay;
struct TREE
{
void add(int u,int v)
{
to[++cnt]=v; next[cnt]=front[u]; front[u]=cnt;
}
void dfs(int u,int f)
{
Splay.insert(u,f,a[u]);
for(int i=front[u];i;i=next[i])
dfs(to[i],u);
}
}Tree;
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
int u,v;
for(int i=;i<n;i++)
{
u=read(); v=read();
Tree.add(++u,++v);
}
l[]=++tot; r[]=++tot;
siz[]=; siz[]=;
fa[]=; ch[][]=;
Tree.dfs(,);
m=read();
int op; long long x;
while(m--)
{
op=read(); x=read2(); x+=special; x++;
if(op==) { u=read(); Splay.insert(++n,x,u); }
else if(op==) { u=read(); Splay.add(x,u); }
else if(op==) Splay.del(x);
else Splay.query(x);
}
}

Codechef Dynamic Trees and Queries的更多相关文章

  1. [CodeChef-ANUDTQ] Dynamic Trees and Queries

    类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了.注意sum和lastans是long long. #include<cstdio> #include<algorith ...

  2. codechef Dynamic GCD [树链剖分 gcd]

    Dynamic GCD 题意:一棵树,字词树链加,树链gcd 根据\(gcd(a,b)=gcd(a,a-b)\) 得到\(gcd(a_1, a_2, ..., a_i) = gcd(a_1, a_1- ...

  3. CodeChef Dynamic GCD

    嘟嘟嘟vjudge 我今天解决了一个历史遗留问题! 题意:给一棵树,写一个东西,支持一下两种操作: 1.\(x\)到\(y\)的路径上的每一个点的权值加\(d\). 2.求\(x\)到\(y\)路径上 ...

  4. Creating dynamic/configurable parameterized queries in Entity Framework

    https://dillieodigital.wordpress.com/2013/05/09/creating-dynamicconfigurable-parameterized-queries-i ...

  5. codechef : TREDEG , Trees and Degrees

    其实有原题,生成树计数 然鹅这题里面是两道题, 50pts 可以用上面那题的做法直接过掉,另外 50pts 要推推式子,搞出 O n 的做法才行(毕竟多项式常数之大您是知道的) 虽说这道题里面是没有 ...

  6. 【CF375D】Trees and Queries——树上启发式合并

    (题面不是来自Luogu) 题目描述 有一个大小为n且以1为根的树,树上每个点都有对应的颜色ci.现给出m次询问v, k,问以v为根的子树中有多少种颜色至少出现了k次. 输入格式 第一行两个数n,m表 ...

  7. EF 5 最佳实践白皮书

    Performance Considerations for Entity Framework 5 By David Obando, Eric Dettinger and others Publish ...

  8. FTP客户端上传下载Demo实现

    1.第一次感觉MS也有这么难用的MFC类: 2.CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归),采用队列存储目录再依次下载: 3.本程序支持文件夹嵌套上传下载: ...

  9. 10+ 最流行的 jQuery Tree 菜单插件

    jstree – jQuery Tree Plugin With HTML & JSON Data jstree is a lightweight and flexible jQuery pl ...

随机推荐

  1. Scrum立会报告+燃尽图(Beta阶段第一次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://coding.net/u/wuyy694 ...

  2. DWZ-JUI+UEditor第二次不显示,UEditor异步加载第二次不显示的解决方案

    使用UEditor-1.4.3中遇到第一次跳转到使用UEditor的界面后,编辑器加载正常,返回后第二次再跳转到这个界面就出现UEditor无法正常加载, 也没百度到答案,看UEditor源码,发现这 ...

  3. alpha发布评论

    飞天小女警我们自己的礼物挑选工具完整度不高,页面简陋,还有很多需要完善和改进的地方,空间比较大,但是本身能力太不足. 个人比较喜欢奋斗吧兄弟做的食物链系统.感觉是可以拿来用的工具吧. 天天向上的游戏连 ...

  4. (六)Jmeter重要组件的执行顺序及作用域

    一.Jmeter重要组件: 1)配置元件---Config Element: 用于初始化默认值和变量,以便后续采样器使用.配置元件大其作用域的初始阶段处理,配置元件仅对其所在的测试树分支有效,如,在同 ...

  5. 守护线程以及要使用时注意的一点(Daemon Thread)

    在Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) Daemon的作用是为其他线程的运行提供便利服务,比如垃圾回收线程就是一个很称职的守护者.User和 ...

  6. Javascript中判断变量是数组还是对象(array还是object)

    怎样判断一个JavaScript变量是array还是obiect? 答案: 1.如果你只是用typeof来检查该变量,不论是array还是object,都将返回‘objec'. 此问题的一个可行的答案 ...

  7. BZOJ 1925 地精部落(DP)

    一道很经典的DP题. 题意:求n排列中波动排列的种数. 不妨考虑DP,令dp1[i][j],表示1-j的排列中,第一项为i之后递增的波动排列种数.dp2[i][j]表示1-j的排列中,第一项为i之后递 ...

  8. 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆

    题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...

  9. Java虚拟机内存模型和volatile型变量

    Java虚拟机内存模型 了解Java虚拟机的内存模型,有助于我们明白为什么会发生线程安全问题. 上面这幅图是<深入理解Java虚拟机-JVM高级特性与最佳实践>的书中截图. 线程共享的变量 ...

  10. 【Java】关于@RequestBody

    首先@RequestBody需要接的参数是一个string化的json,这里直接使用JSON.stringify(json)这个方法来转化 其次@RequestBody,从名称上来看也就是说要读取的数 ...