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 ...
随机推荐
- Python学习日志_2017/09/09
今天早晨学习<Head First HTML and CSS>.随着内容逐渐深入,知识量逐渐增加,今天早晨三个小时学习了一章:<Html的基本元素>,学到了不少的东西.比如,什 ...
- java 使用htmlunit模拟登录爬取新浪微博页面
mport java.io.IOException;import java.net.MalformedURLException;import com.gargoylesoftware.htmlunit ...
- Higher level thinking
「Higher level thinking」-- 出自 Ray Dalio 的<Principles>(PDF 原文:Principles by Ray Dalio) Higher le ...
- atom 自定义快捷键
'atom-text-editor': 'shift-alt-i':'core:move-up' 'shift-alt-space':'core:move-down' 'shift-alt-l':'c ...
- PyCharm如何配置断点调试功能
1. 点击菜单 PyCharm -> Preferences.. 2. 在左侧菜单栏找到Project:Django - > Project Interpreter 并点击配置 Proje ...
- 安装VC++6.0实验环境
安装VC++6.0步骤:(1)下载一个压缩包进行解压(2)点击打开解压后的文件(3)找到文件里的程序进行安装(4)等待安装完成该程序后可以试着运行一下此程序,在此我们需要了解编写程序的步骤和注意事项. ...
- off-by-one&doublefree. 看雪10月ctf2017 TSRC 第四题赛后学习
off-by-one 0x00 发现漏洞 1.off-by-one 在massage函数中,如图所示,可以修改的字节数比原内存大小多了一个字节 2.悬挂指针 可以看到,在free堆块的时候,没有清空指 ...
- 搭建SSI开发框架原理
Spring2.5.Struts2.Ibatis开发框架搭建(一) ssi, ibatis 一.框架下载 1.1 Struts2框架 Struts2框架发展于WebWork,现在捐献给了Apach ...
- jquery动态实现填充下拉框
当点下拉框时动态加载后台数据. 后台代码 protected void doPost(HttpServletRequest request, HttpServletResponse response) ...
- fckeditor配置详解
使用配置设置: . FCKConfig.CustomConfigurationsPath = '' ; // 自定义配置文件路径和名称 . FCKConfigFCKConfig.EditorAreaC ...