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 ...
随机推荐
- 在windows和unbuntu上安装octave
windows安装octave 安装wiki Octave ftp库 从上述的库中可以找到对应的版本的octave的exe安装程序,或者是zip等的压缩包,建议直接下载对应系统的exe执行文件.安装. ...
- lintcode-420-报数
420-报数 报数指的是,按照其中的整数的顺序进行报数,然后得到下一个数.如下所示: 1, 11, 21, 1211, 111221, ... 1 读作 "one 1" -> ...
- WPF和Expression Blend开发实例:充分利用Blend实现一个探照灯的效果
本篇文章阅读的基础是在读者对于WPF有一定的了解并且有WPF相关的编码经验,对于Blend的界面布局有基础的知识.文章中对于相应的在Blend中的操作进行演示,并不会进行细致到每个属性的介绍.同时,本 ...
- so加载报错:dlopen failed: couldn't map ... Permission denied
转自:https://blog.csdn.net/u013270444/article/details/60869376 问题描述: 我的应用当中集成了一个安全相关的sdk,而这个sdk中使用的so是 ...
- crontab & php实现多进程思路
<?php $startTime = time(); while(1) { if (time() - $startTime > 600) { exit; } // ... Do SomeT ...
- elasticsearch6 学习之基础CURD
环境:elasticsearch6.1.2 kibana6.1.2 基础概念: 1._index元数据 (1)代表一个document存放在哪个index中(2)类似的数据放在一个索引 ...
- git commad
repo forall -c 'echo $REPO_PATH;ssh trd.git.htc.com -p29419 -lowen_wen gerrit create-project --submi ...
- elsarticle模板 去掉摘要前后的两条横线
参考:http://www.newsmth.net/nForum/#!article/TeX/316697?au=ericfire 如图:使用elsarticle模板修改PDF格式,去掉摘要前后的横线 ...
- wp开发(三)--赚取收益篇
App开发完毕了,是否有赚取收益的想法呢?下面很浅显地介绍两种常用赚取收益的方法. 一. 收费 在发布应用时,可以对应用进行定价,发布到商城之后,用户付费才可以下载,当然也可以提供试用版.收益状况可以 ...
- 关于setInterval()定时
最近项目中,遇到个需求就是获取停车场剩余车位数量,想是通过ajax定时抓取接口数据来实现(本想通过SignalR),但是项目本身直供少数人使用,感觉定时ajax可以满足 下面上代码 var handl ...