[Split The Tree][dfs序+树状数组求区间数的种数]
Split The Tree
时间限制: 1 Sec 内存限制: 128 MB
提交: 46 解决: 11
[提交] [状态] [讨论版] [命题人:admin]
题目描述
We define the weight of a tree as the number of different vertex value in the tree.
If we delete one edge in the tree, the tree will split into two trees. The score is the sum of these two trees’ weights.
We want the know the maximal score we can get if we delete the edge optimally.
输入
n
p2 p3 . . . pn
w1 w2 . . . wn
Constraints
2 ≤ n ≤ 100000 ,1 ≤ pi < i
1 ≤ wi ≤ 100000(1 ≤ i ≤ n), and they are integers
pi means there is a edge between pi and i
输出
样例输入
3
1 1
1 2 2
样例输出
3
题意:给一棵树,每个节点都有权值,删除一条边会变成两棵树,每棵树的价值是树上不同权值的个数,求max(两棵树的价值和)
题解:dfs序可以将树上的问题转化为易于操作的线性区间问题(子树是dfs序中连续的区间)。这题通过dfs序转化为求区间数字的种数,通过树状数组求解。注意求区间数的种数的方法:通过vector存储区间左端点,从总区间的起始点开始往后遍历,不断update树状数组中当前点代表权值的位置(即把当前点权值的上一个位置的值-1,把当前位置+1),并且用树状数组计算以当前点为终点的区间种数和
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
struct edge{
int x;
int y;
int nex;
}e[];
struct pot{
int pre;
int id;
};
vector<struct pot>g[];
int n,cnt,tot,head[],q[],w[],c[],dfn[],r[],vis[],ans[];
void adde(int x1,int y1){
e[cnt].x=x1;
e[cnt].y=y1;
e[cnt].nex=head[x1];
head[x1]=cnt++;
}
int lowbit(int x){
return x&(-x);
}
void update(int x,int y,int n){
for(int i=x;i<=n;i+=lowbit(i))
c[i] += y;
}
int query(int x){
int ak=;
for(int i=x;i>;i-=lowbit(i)){
ak+=c[i];
}
return ak;
}
void dfs(int u,int fa){
w[++tot]=u;
w[tot+n]=u;
dfn[u]=tot;
for(int i=head[u];i!=-;i=e[i].nex){
int v=e[i].y;
if(v==fa)continue;
if(dfn[v])continue;
dfs(v,u);
}
r[u]=tot;
}
int main(){
scanf("%d",&n);
memset(head,-,sizeof(head));
for(int i=;i<=n;i++){
int a;
scanf("%d",&a);
adde(a,i);
adde(i,a);
}
for(int i=;i<=n;i++){
scanf("%d",&q[i]);
}
dfs(,-);
for(int i=;i<cnt;i+=){
int u=e[i].x;
int v=e[i].y;
int L=dfn[u];
int R=r[u];
int L1=dfn[v];
int R1=r[v];
struct pot aaa,bbb;
if(R!=n){
aaa.id=i;
aaa.pre=L;
bbb.id=i;
bbb.pre=R+;
g[R].push_back(aaa);
g[L-+n].push_back(bbb);
}
else{
aaa.id=i;
aaa.pre=L1;
bbb.id=i;
bbb.pre=R1+;
g[R1].push_back(aaa);
g[L1-+n].push_back(bbb);
}
}
for(int i=;i<=n*;i++){
if(vis[q[w[i]]]){
update(vis[q[w[i]]],-,n*);
}
vis[q[w[i]]]=i;
update(vis[q[w[i]]],,n*);
for(int j=;j<g[i].size();j++){
struct pot ccc=g[i][j];
ans[ccc.id]+=query(i)-query(ccc.pre-);
}
}
int ans0=;
for(int i=;i<cnt;i+=){
ans0=max(ans0,ans[i]);
}
cout<<ans0<<endl;
return ;
}
[Split The Tree][dfs序+树状数组求区间数的种数]的更多相关文章
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- [poj3321]Apple Tree(dfs序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26762 Accepted: 7947 Descr ...
- POJ3321Apple Tree Dfs序 树状数组
出自——博客园-zhouzhendong ~去博客园看该题解~ 题目 POJ3321 Apple Tree 题意概括 有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作: 1.改变其 ...
- POJ 3321 Apple Tree DFS序 + 树状数组
多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...
- Codeforces Round #381 (Div. 2) D. Alyona and a tree dfs序+树状数组
D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)
http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
随机推荐
- [BOZJ2721]樱花
题目求\(\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\)已知n, x和y的正整数解的个数 设z=\(n!\) \(\frac{1}{x}+\frac{1}{y}=\fra ...
- 经典排序js实现
https://www.cnblogs.com/onepixel/articles/7674659.html
- pytest文档14-函数传参和firture传参数request
前言 为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...
- Android Studio 使用本地gradle配置详解
由于国内墙的原因,我们的Gradle无法使用 但是我们可以通过去下载我们想要的Gradle版本 然后再AndoidStudio内去配置本地的版本 进而去实现了Gradle的配置 注意一: so我们按照 ...
- mpvue构建小程序(步骤+地址)
mpvue 是一个使用 Vue.js 开发小程序的前端框架(美团的开源项目).框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运 ...
- 『PyTorch x TensorFlow』第六弹_从最小二乘法看自动求导
TensoFlow自动求导机制 『TensorFlow』第二弹_线性拟合&神经网络拟合_恰是故人归 下面做了三个简单尝试, 利用包含gradients.assign等tf函数直接构建图进行自动 ...
- vue去掉#——History模式
打开index.js文件 加在 Vue.use(Router) export default new Router({ mode: 'history', ] }) 若有不明白请加群号:复制 69518 ...
- redis基础学习总结
学习目标: 1.redis特点及安装 2.redis键值操作 3.redis数据类型[string, link,set,orderset,hash] 4.事务 5.消息 ...
- js获取谷歌浏览器版本
根据浏览器的useragent获取浏览器信息 // 获取谷歌浏览器版本 function getChromeVersion() { var arr = navigator.userAgent.spli ...
- day38-多进程多线程-进程池
强大的Manage上一篇的数据共享的方式只有两种结构Value和Array.Python中提供了强大的Manage专门用来做数据共享的,其支持的类型非常多,包括,Value, Array,list,d ...