Split The Tree

时间限制: 1 Sec  内存限制: 128 MB
提交: 46  解决: 11
[提交] [状态] [讨论版] [命题人:admin]

题目描述

You are given a tree with n vertices, numbered from 1 to n. ith vertex has a value wi
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.

输入

Input is given from Standard Input in the following format:
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

输出

Print one number denotes the maximal score.

样例输入

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序+树状数组求区间数的种数]的更多相关文章

  1. 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 ...

  2. 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 ...

  3. [poj3321]Apple Tree(dfs序+树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Descr ...

  4. POJ3321Apple Tree Dfs序 树状数组

    出自——博客园-zhouzhendong ~去博客园看该题解~ 题目 POJ3321 Apple Tree 题意概括 有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作: 1.改变其 ...

  5. POJ 3321 Apple Tree DFS序 + 树状数组

    多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...

  6. 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 ...

  7. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  8. 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 ...

  9. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

随机推荐

  1. kindeditor4.1.11的使用方法

    在引入某个外部框架/功能件的 时候, 通常是 先引入css, 后引入js. css的必要属性是rel和href, js的必要属性是charset和src. js都是用javascript的,所以 cs ...

  2. Learning-Python【30】:基于UDP协议通信的套接字

    UDP协议没有粘包问题,但是缓冲区大小要足够装数据包大小,建议不要超过 512 服务端: # 服务端 import socket server = socket.socket(socket.AF_IN ...

  3. vi中换行、翻页和查找功能

    vi时,按ESC进入Command模式, 1. 移动光标命令:j 向下移动一行:k 向上移动一行:h 向左移动一个字符:l 向右移动一个字符:对于 j.k.l和h键,命令前加数字,移动多行:如 3j, ...

  4. Leetcode480-Binary Tree Paths-Easy

    480. Binary Tree Paths Given a binary tree, return all root-to-leaf paths. Example Example 1: Input: ...

  5. datetime字符串中含T

    json序列化datetime类型,返回给前端进行展示,字符串带T 例如:var time = 2018-08-08T09:07:04.767  =>  time.substr(0, 16).r ...

  6. Python语法注意点

    1. 在Python中定义函数,可以用必选参数.默认参数.可变参数.关键字参数和命名关键字参数,这5种参数都可以组合使用.但是请注意,参数定义的顺序必须是:必选参数.默认参数.可变参数.命名关键字参数 ...

  7. HTML5 FormData方法介绍

    详细见链接 转载说明:转自CSDN上“诗渊”的博客

  8. Regex-Golf

    A man, a plan: 判断回文,如果不确定串长度情况下可以考虑利用反向引用构造pattern,例如: (.)\1  , (.)(.)\2\1 , (.)(.)(.)\3\2\1 ...但这里只 ...

  9. jQuery抽奖插件 jQueryRotate

    实现代码 网页中引用 <script type="text/javascript" src="js/jquery.min.js"></scri ...

  10. two week summary

    from collections import Iteratorfrom collections import Iterabl dic = {'a':"a","91a&q ...