[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 ...
随机推荐
- Python3 tkinter基础 Menu add_radiobutton 单选的下拉菜单
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- FJUT3701 这也是一道数论题(线段树)题解
Problem Description 好久没出数据结构题,现在赶紧来做道数据结构题热热身 小q现在要去银行,他有个很厉害的bug能看到前面排队的人.假如当前有人正在办理业务,那么肯定要等待前一个人完 ...
- oracle substr函数
//截取下划线后的字符串 select substr('GY_272',instr('GY_272', '_', -1, 1)+1) from dual select substr('GY_272 ...
- [译]RabbitMQ教程C#版 - "Hello World"
先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...
- winform左右滑动
public static class FormTransform { public static void TransformSize(Form frm, int newWidth, int new ...
- Redhat中关于httpd仓库安装的简要步骤
创建repo-server: yum install httpd yum install httpd -y < -y 表示在安装过程中与界面交互时自动答复yes >sys ...
- CAM(Content Addressable Memory)介绍
CAM是一种特殊的存储器.所谓CAM,即内容寻址存储器.CAM存储器在其每个存储单元都包含了一个内嵌的比较逻辑,写入CAM的数据会和其内部存储的每一个数据进行比较,并返回与端口数据相同的所有内部数据的 ...
- HostPort和NodePort
https://blog.51cto.com/12462495/2163239?source=dra
- Linux虚拟机的三种网络连接方式
Linux虚拟机的三种网络连接方式 虚拟机网络模式 无论是vmware,virtual box,virtual pc等虚拟机软件,一般来说,虚拟机有三种网络模式: 1.桥接 2.NAT 3.Host- ...
- django2_开发web系统接口
1.单独创建.../sign/views_if.py文件,开发添加发布会接口 from django.http import JsonResponse from cmdb.models import ...