Codechef Dynamic Trees and Queries
Home » Practice(Hard) » Dynamic Trees and Queries
Problem Code: ANUDTQ
Submit
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的更多相关文章
- [CodeChef-ANUDTQ] Dynamic Trees and Queries
类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了.注意sum和lastans是long long. #include<cstdio> #include<algorith ...
- 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- ...
- CodeChef Dynamic GCD
嘟嘟嘟vjudge 我今天解决了一个历史遗留问题! 题意:给一棵树,写一个东西,支持一下两种操作: 1.\(x\)到\(y\)的路径上的每一个点的权值加\(d\). 2.求\(x\)到\(y\)路径上 ...
- Creating dynamic/configurable parameterized queries in Entity Framework
https://dillieodigital.wordpress.com/2013/05/09/creating-dynamicconfigurable-parameterized-queries-i ...
- codechef : TREDEG , Trees and Degrees
其实有原题,生成树计数 然鹅这题里面是两道题, 50pts 可以用上面那题的做法直接过掉,另外 50pts 要推推式子,搞出 O n 的做法才行(毕竟多项式常数之大您是知道的) 虽说这道题里面是没有 ...
- 【CF375D】Trees and Queries——树上启发式合并
(题面不是来自Luogu) 题目描述 有一个大小为n且以1为根的树,树上每个点都有对应的颜色ci.现给出m次询问v, k,问以v为根的子树中有多少种颜色至少出现了k次. 输入格式 第一行两个数n,m表 ...
- EF 5 最佳实践白皮书
Performance Considerations for Entity Framework 5 By David Obando, Eric Dettinger and others Publish ...
- FTP客户端上传下载Demo实现
1.第一次感觉MS也有这么难用的MFC类: 2.CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归),采用队列存储目录再依次下载: 3.本程序支持文件夹嵌套上传下载: ...
- 10+ 最流行的 jQuery Tree 菜单插件
jstree – jQuery Tree Plugin With HTML & JSON Data jstree is a lightweight and flexible jQuery pl ...
随机推荐
- 线段树---成段更新hdu1698 Just a Hook
hdu1698 Just a Hook 题意:O(-1) 思路:O(-1) 线段树功能:update:成段替换 (由于只query一次总区间,所以可以直接输出1结点的信息) 题意:给一组棍子染色,不同 ...
- UVALive - 6887 Book Club 有向环的路径覆盖
题目链接: http://acm.hust.edu.cn/vjudge/problem/129727 D - Book Club Time Limit: 5000MS 题意 给你一个无自环的有向图,问 ...
- SQL Server数据库复制
事务复制 事务复制是一种复制类型,对订阅服务器上应用的初始数据快照,然后当发布服务器上发生数据修改时,将捕获到个别的事务并传播到订阅服务. 事务复制的原理是先将发布服务器数据库中的初始快照发送到各订阅 ...
- cobbler-web 网络安装服务器套件 Cobbler(补鞋匠)
Cobbler作为一个预备工具,使部署RedHat/Centos/Fedora系统更容易,同时也支持Suse和Debian系统的部署. 它提供以下服务集成: * PXE服务支持 * DHCP服务管 ...
- Hbase的安装和配置
1,准备好hbase的linux环境下的压缩包,这里hadoop版本为hadoop2.5.0,hbase版本为 2,解压缩这个版本,不选src的,其实两个任一都行 进入到hbase安装包目录,我这里的 ...
- 用到的C++标准库
std::set<type>, 模板写的平衡二叉树的集合容器, method: insert, count, std:map<int, string>, 映射和多重映射基于某一 ...
- PHP用抛物线的模型实现微信红包生成算法的程序源码
<?php /* *Author:Kermit *Time:2015-8-26 *Note:红包生成随机算法 */ header("Content-type:text/html;cha ...
- java多线程之CAS原理
前言 在Java并发包中有这样一个包,java.util.concurrent.atomic,该包是对Java部分数据类型的原子封装,在原有数据类型的基础上,提供了原子性的操作方法,保证了线程安全.下 ...
- [计算机网络-数据链路层] CSMA、CSMA/CA、CSMA/CD详解
1.CSMA(载波侦听多路访问协议) CSMA 当其他节点检测到信道被占用时不发送数据.但是当数据发送完后其他节点同时检测到信道为空闲,之后又在同一时刻发送数据,可能再次产生冲突. 2.CSMA/CD ...
- 怎么用JavaScript实现tab切换
先看一下代码实现后的最终效果: 用JavaScript实现思路很简单,就是先把所有的内容隐藏,点击标题对应的内容显示, css代码如下: <style type="text/css&q ...