Split The Tree
Split The Tree
时间限制: 1 Sec 内存限制: 128 MB
题目描述
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
来源/分类
题意:每颗树的重量定义为这颗树上所有节点权值不同的个数,现在要割掉一条边,求生成的两颗树最大的重量和。
做法:dfs序,然后枚举每一条边,删除这条边就相当于在dfs序中取走了一个区间,问题就变成了求区间不同数的个数。取走一个区间后,剩下的两块区间求不同数个数可以通过把区间加长一倍来做。
#include<bits/stdc++.h>
#define N 100050
using namespace std; vector<int>edge[N];
int w[N];
int children[N]={},number[N]={},dfsorder[N],len=; int dfs(int x)
{
dfsorder[++len]=x;
number[x]=len;
children[x]=; int Size=edge[x].size();
for(int i=;i<Size;i++)
if(number[edge[x][i]]==)
{
children[x]+=dfs(edge[x][i]);
}
return children[x];
} struct ss
{
int l,r,index,ans; bool operator < (const ss& s) const
{
return r<s.r;
}
};
vector<ss>interval; int c[*N+]={};
void updata(int x,int v)
{
for(int i=x;i<*N;i+=i&(-i))c[i]+=v;
} int Sum(int x)
{
int ans=;
while(x>)
{
ans+=c[x];
x-=x&(-x);
}
return ans;
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int p;
scanf("%d",&p);
edge[i].push_back(p);
edge[p].push_back(i);
} for(int i=;i<=n;i++)scanf("%d",&w[i]); dfs(); for(int i=;i<=n;i++)
{
interval.push_back((ss){number[i],number[i]+children[i]-,i,});
interval.push_back((ss){number[i]+children[i],n+number[i]-,i,});
}
for(int i=;i<=n;i++)
{
dfsorder[i]=w[dfsorder[i]];
dfsorder[n+i]=dfsorder[i];
}
sort(interval.begin(),interval.end()); int last[N]={};
int c1=; for(int i=;i<*n;i++)
{
if(interval[i].l>interval[i].r)continue; for(int j=c1;j<=interval[i].r;j++)
{
if(last[dfsorder[j]]==)
{
updata(j,);
last[dfsorder[j]]=j;
}
else
{
updata(last[dfsorder[j]],-);
updata(j,);
last[dfsorder[j]]=j;
}
}
interval[i].ans=Sum(interval[i].r)-Sum(interval[i].l-);
c1=interval[i].r+;
} int sum[N]={},ans=; for(int i=;i<*n;i++)
{
sum[interval[i].index]+=interval[i].ans;
ans=max(ans,sum[interval[i].index]);
} printf("%d\n",ans);
return ;
}
Split The Tree的更多相关文章
- [Split The Tree][dfs序+树状数组求区间数的种数]
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB提交: 46 解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...
- [CodeForces1059E] Split the Tree
树形DP. 用倍增处理出来每个点往上能延伸出去的最远路径,nlogn 对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x] #inclu ...
- HDU6504 Problem E. Split The Tree【dsu on tree】
Problem E. Split The Tree Problem Description You are given a tree with n vertices, numbered from 1 ...
- Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)
https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...
- [CF1059E]Split the Tree[贪心+树上倍增]
题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...
- Codeforces 1059E. Split the Tree
题目:http://codeforces.com/problemset/problem/1059/E 用倍增可以在nlog内求出每个节点占用一个sequence 时最远可以向父节点延伸到的节点,对每个 ...
- CF1059E Split the Tree(倍增)
题意翻译 现有n个点组成一棵以1为根的有根树,第i个点的点权为wi,需将其分成若干条垂直路径使得每一个点当且仅当被一条垂直路径覆盖,同时,每条垂直路径长度不能超过L,点权和不能超过S,求最少需要几条垂 ...
- Codeforces 461B. Appleman and Tree[树形DP 方案数]
B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- CF461B Appleman and Tree (树DP)
CF462D Codeforces Round #263 (Div. 2) D Codeforces Round #263 (Div. 1) B B. Appleman and Tree time l ...
随机推荐
- SQL Server2005的数据还原与备份具体步骤
一:备份数据库步骤 1. 第一步:在开始—>程序(P)—>MicrosoftSQLserver2005—>SQLServerManagementStudio(如下图) 2. 第二步: ...
- js生成txt文件
HTML CODE: <div class="modal-footer"> <a onfocus="this.blur();" id=&quo ...
- javascript基本类型和引用类型,作用域和内存问题
基本类型(null.undefined.boolean.number.string)和引用类型(Object 对象) 1 基本类型:只能不存一个值,一种类型:从一个变量向另一个变量复制基本类型的值, ...
- currentStyle和getComputedStyle来获取外部样式
currentStyle和getComputedStyle来获取外部样式 通过document.getElementById(id).style.XXX就可以获取到XXX的值,但意外的是,这样做只能取 ...
- python matplotlib 可视化操作实例
具体代码: # encoding: utf-8 # coding = utf-8 import sys reload(sys) sys.setdefaultencoding('utf8') from ...
- 第2节 azkaban调度:17、azkaban的两个服务模式的安装
2.3.3.azkaban两个服务模式安装 1.确认所需软件: Azkaban Web服务安装包 azkaban-web-server-0.1.0-SNAPSHOT.tar.gz Azkaban执行服 ...
- css3中animation属性animation-timing-function知识点以及其属性值steps()
在animation中最重要的其实就是时间函数(animation-timing-function)这个属性,他决定了你的动画将以什么样的速度执行,所以最关键的属性值也就是cubic-bezier(n ...
- Java中的线程--线程中的工具
这主要想写一下Java中的jdk提供的一些线程中的工具, 一.semaphore信号灯 Semaphore可以维护当前访问自身的线程个数,并提供了同步机制,使用Semaphore可以控制同时访问资源的 ...
- <MySQL>入门一 查询 DQL
1. 数据库表 1.1 员工表 Create Table CREATE TABLE `employees` ( `employee_id` ) NOT NULL AUTO_INCREMENT, `fi ...
- mysql查询数据包太大:max_allowed_packet
查询大小: show variables like '%max_allowed_packet%'; 修改大小: set global max_allowed_packet = 1024 * 1024 ...