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. vim 编码方式的设置

    和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2.UTF-8 等流行的 Unicode 编码方式.然而不幸的是,和很多来自 Linux 世界的软件一样,这需要 ...

  2. 404 Note Found -(课堂实战)- 项目UML设计(团队)

    目录 团队信息 分工选择 课上分工 课下分工 ToDolist alpha版本要做的事情 燃尽图 UML 用例图 状态图 活动图 类图 部署图 实例图 对象图 时序图 包图 通信图 贡献分评定 课上贡 ...

  3. lintcode-129-重哈希

    129-重哈希 哈希表容量的大小在一开始是不确定的.如果哈希表存储的元素太多(如超过容量的十分之一),我们应该将哈希表容量扩大一倍,并将所有的哈希值重新安排.假设你有如下一哈希表: size=3, c ...

  4. websocket服务器+客户端

    <?php $demo = new ws('192.168.90.47',12345); $demo->run(); class ws { //当前服务端主连接 private $curr ...

  5. c语言----程序记录

    1.结构体写入文件,读取 #include <stdio.h> #include <string.h> #include <stdlib.h> #define ma ...

  6. MAC 下用 brew 搭建 PHP 开发环境

    Mac下用brew搭建PHP(LNMP/LAMP)开发环境 Mac下搭建lamp开发环境很容易,有xampp和mamp现成的集成环境.但是集成环境对于经常需要自定义一些配置的开发者来说会非常麻烦,而且 ...

  7. c#对一个类的扩展

    首先定义一个静态类,参数使用this约束并选择需要扩展的类,当然也可以 继续添加扩展是需要添加的参数 public static class StringExrprp { /// <summar ...

  8. 【插件】LinqToExcel常用对象

    1.ExcelQueryFactory对象(1)获取工作表名集合IEnumerable<string> GetWorksheetNames() //获取工作薄中的工作表名foreach ( ...

  9. ZOJ3466-The Hive II

    题意 有一个六边形格子,共 \(n\) 行,每行有 8 个位置,有一些格子不能走.求用一些环覆盖所有可走格子的方案数.\(n\le 10\) . 分析 插头dp,只不过是六边形上的,分奇数列和偶数列讨 ...

  10. a++ 和 ++a 的区别

    a++ 和 ++a 的区别 1)首先说左值和右值的定义:        变量和文字常量都有存储区,并且有相关的类型.区别在于变量是可寻址的(addressable)对于每一个变量都有两个值与其相联:  ...