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. elementUI使用本地变量进行验证,监测不到本地变量的变化 的问题

    对于饿了么组件自定义验证规则,组件库文档已经非常详细了:http://element-cn.eleme.io/#/zh-CN/component/form 我这里将验证中固定的值提取出来使用变量进行保 ...

  2. jquery validate 一个注册表单的应用

    先看页面 前端表单代码  register.html <form class="mui-input-group" id="regForm"> < ...

  3. 有道云笔记web版本居然不支持火狐

    好尴尬的火狐呀....

  4. solrCloud源码分析之CloudSolrClient

    CloudSolrClient是solrj提供的客户端与solrCloud交互的类.该类的实例与zookeeper进行通信来确定solrCloud collections中的solr endpoint ...

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

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

  6. App简介及登录页面

    一. APP目录 app目录: -migrations 数据操作记录,是自动创建的.数据修改表结构 -__init__.py #在python3里面可有可无都行 -__init__.py -admin ...

  7. JavaScript中“&&”和“||”操作符的意义,深入理解和使用场景

     一.概念 与其他语言不同,在js中,逻辑运算符可以返回任何类型的数据,不仅仅是true和false. &&和||的返回值是两个操作数的其中一个.即a&&b或者a||b ...

  8. XML 增加属性

    var resultDoc = new XmlDocument(); resultDoc.LoadXml("<root></root>"); resultD ...

  9. 一些noip模拟题一句话题解

    Problem A: 序列 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 12  Solved: 9[Submit][Status][Web Boar ...

  10. BZOJ 3786: 星系探索 解题报告

    3786: 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅 ...