RXD, tree and sequence

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 234    Accepted Submission(s): 82

Problem Description
RXD has a rooted tree T with size n, the root ID is 1, with the depth of 1
RXD has a permutation P with size n.
RXD wants to divide the permutaion into k continuous parts 
For each part, he would calculate the depth of the least common ancestor of the part. And finally accumulate them. 
He wants to make the final result minimized. 
Please calculate the minimal answer.
1≤k≤n≤3×105,n×k≤3×105
Input
There are several test cases, please keep reading until EOF.
For each test case, the first line consists of 2 integer n,k, which means the number of the tree nodes and the size of the permutaion, and k means the number of parts.
The next line consists of n different integers, which means the permutation P.
The next n−1 lines consists of 2 integers, a,b, means a tree edge.
It is guaranteed that the edges would form a tree.
There are 6 test cases.
Output
For each test case, output an integer, which means the answer.
Sample Input
6 3
4 6 2 5 1 3
1 2
2 3
3 4
4 5
4 6
Sample Output
6
Source

【题意】给你一棵树,然后给你树的节点编号的一种排列,然后要你将这个序列分成非空的k份,对于每一份求lca的深度,然后累加,   求和最小。

【分析】首先得想到区间lca的一个性质,对于区间[i,j],他们的lca肯定是lca[i,i+1],lca[i+1,i+2],...lca[j-1,j]中的某一个,也就是说,对于某一个区间,决定lca的只有某相邻的两个数。然后在这个序列中,对于某一个数,他有三种存在状态。第一,它存在于某个区间,但是这个区间的lca不是由它决定的。第二,它一个数本身作为一份。第三,它和它左边的数的lca作为某一份的lca。然后dp[i][j]表示前i个数分成j段的最小答案,对于上面三种情况分别对应三个方程

dp[i][j]=min(dp[i][j],dp[i-1][j]);
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+dep[a[i]]);
dp[i][j]=min(dp[i][j],dp[i-2][j-1]+lca[i]);

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 5e5+;
const int M = ;
const int mod = 1e9+;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,k,ans;
int dep[N],fa[N][];
int a[N],lca[N];
vector<int>edg[N];
void dfs(int u,int f){
fa[u][]=f;
for(int i=;i<;i++){
fa[u][i]=fa[fa[u][i-]][i-];
}
for(int v : edg[u]){
if(v==f)continue;
dep[v]=dep[u]+;
dfs(v,u);
}
}
int LCA(int u,int v){
int U=u,V=v;
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v]){
u=fa[u][i];
}
}
if(u==v)return (u);
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];v=fa[v][i];
}
}
return (fa[u][]);
} int main(){
while(~scanf("%d%d",&n,&k)){
int dp[n+][k+];
met(dp,inf);
for(int i=;i<=n;i++)scanf("%d",&a[i]),edg[i].clear();
for (int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
edg[u].pb(v);
edg[v].pb(u);
}
dep[]=;
dfs(,);
dp[][]=;
for(int i=;i<=n;i++){
int m = LCA(a[i-],a[i]);
lca[i]=dep[m];
}
for(int i=;i<=n;i++){
for(int j=;j<=min(i,k);j++){
if(i->=j)dp[i][j]=min(dp[i][j],dp[i-][j]);
if(j>)dp[i][j]=min(dp[i][j],dp[i-][j-]+dep[a[i]]);
if(j>&&i>=&&j-<=i-)dp[i][j]=min(dp[i][j],dp[i-][j-]+lca[i]);
}
}
printf("%d\n",dp[n][k]);
}
return ;
}

HDU 6065 RXD, tree and sequence (LCA DP)的更多相关文章

  1. HDU 6065 RXD, tree and sequence (LCA+DP)

    题意:给定上一棵树和一个排列,然后问你把这个排列分成m个连续的部分,每个部分的大小的是两两相邻的LCA的最小深度,问你最小是多少. 析:首先这个肯定是DP,然后每个部分其实就是里面最小的那个LCA的深 ...

  2. hdu 6065 RXD, tree and sequence

    题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...

  3. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  4. HDU 5794:A Simple Chess(Lucas + DP)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5794 题意:让一个棋子从(1,1)走到(n,m),要求像马一样走日字型并只能往右下角走.里 ...

  5. 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集

    [题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...

  6. HDU 1141---Brackets Sequence(区间DP)

    题目链接 http://poj.org/problem?id=1141 Description Let us define a regular brackets sequence in the fol ...

  7. hdu 2586 How far away ?(LCA模板)(倍增法)

    在dfs的过程中维护三个数组: deep[i],表示i点在树中的深度: grand[x][i],表示x的第2^i个祖先的节点编号: dis[x][i],表示x到它2^i祖 #include<io ...

  8. HDU6446 Tree and Permutation(树上DP)

    传送门:点我 Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (J ...

  9. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

随机推荐

  1. 基于html5的动画库,非svg和canvas

    基于html5的动画库,非svg和canvas https://greensock.com/docs/#/HTML5/GSAP/TweenLite/

  2. 【poj2464】树状数组

    这道题..太特么多细节了.. 题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线, ...

  3. 如何升级nodejs版本 安装n模块报错 npm ERR! notsup Unsupported platform

    如何升级nodejs版本 首先安装n模块, 输入npm install -g n n模块专门用来管理nodejs的版本. 如果出现npm ERR! notsup Unsupported platfor ...

  4. spring项目中web-inf下不能引用页面资源

    1.spring项目结构 2.spring结构说明 web-inf目录是不对外开放的,外部没办法直接访问到(即通过url访问),只有通过映射来访问,如映射一个action或servlet通过服务器端跳 ...

  5. perl6中的hash定义(2)

    use v6; , :b, :!c; say %ha; say %ha<a>; #这里不能用%ha{a}, {a}表示调用a()函数了, 在perl6中, {}有特别函义 say %ha{ ...

  6. TCP之Nagle算法与延迟ACK

    (一)Nagle算法 为了减少网络中小分组的数目,减少网络拥塞的情况.Nagle算法要求在一条TCP连接上最多只能有一个未被确认的未完成小分组,在该分组ACK到达之前不能够发送其他的小分组,发送端需要 ...

  7. 网络设备之pci_driver

    每个pci驱动都有一个pci_driver实例,用以描述驱动名称,支持的设备信息,以及对应的操作函数: /* 描述一个pci设备,每个pci驱动必须创建一个pci_driver实例 */ struct ...

  8. wait与waitpid

    1. 函数原型: #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc ...

  9. 己动手创建最精简的Linux

    己动手创建最精简的Linux http://blog.sina.com.cn/s/blog_71c87c170101e7ru.html 首次 LFS 搭建全过程 http://zmyxn.blog.5 ...

  10. [How to] 使用Xib来创建view

    1.简介 代码库 正如之前博客介绍的,xib可定义页面的某个部分,特别当此部分区域的view集中并且还有一些相互关联性(如隐藏等)是i特别适合使用xib来进行封装. 本文为[How to]使用自定义c ...