CF372D. Choosing Subtree is Fun

Solution

想了一晚都不会,一觉醒来就悟了QwQQwQQwQ
之前一直想着如何用类似树形DPDPDP的方法求出每一个点的贡献再合并,然后突然发现直接枚举区间就行了。

考虑区间确定时,其实就是求区间内节点在原树上的斯坦纳树的点数。
我们枚举左端点lll,显然随着lll的增加,rrr时非降的,因此动态维护斯坦纳树的点数即可。

因为斯坦纳树的边数,就是每个关键点的深度和减去dfsdfsdfs序相邻的关键点的LCALCALCA的深度和,而点数为边数加一。每次操作会加入一个点,删除一个点,用setsetset维护关键点的dfsdfsdfs序,计算贡献即可。

Code

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=1e9+7;
const int MAXN=400005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}
set<int> Set;
vector<int> e[MAXN];
int id[MAXN],dfn[MAXN],DFN=0,dep[MAXN],mn[18][MAXN],n,Log[MAXN],sum=0,k,ans=1,num=0,eul[MAXN],ID[MAXN];
void dfs(int x,int father)
{id[dfn[x]=++DFN]=x,dep[x]=dep[father]+1,ID[eul[x]=++num]=x;for (auto v:e[x])if (v!=father) {dfs(v,x);ID[++num]=x;}
}
void Init()
{for (int i=1;i<=num;i++) mn[0][i]=dep[ID[i]];for (int i=1;i<=17;i++)for (int j=1;j<=num-(1<<i)+1;j++) mn[i][j]=min(mn[i-1][j],mn[i-1][j+(1<<(i-1))]);
}
int getdep(int l,int r)
{l=eul[id[l]],r=eul[id[r]];if (l>r) swap(l,r);int x=Log[r-l+1];return min(mn[x][l],mn[x][r-(1<<x)+1]);
}
void add(int x)
{set<int>::iterator it=Set.lower_bound(x);int nxt,lst;if (it==Set.end()) nxt=*Set.begin(),it--,lst=*it;else if (it==Set.begin()) nxt=*it,lst=*Set.rbegin();else nxt=*it,it--,lst=*it;if (nxt==lst) sum+=getdep(lst,lst)+getdep(x,x)-getdep(x,lst)*2;else sum+=getdep(x,x)+getdep(lst,nxt)-getdep(x,nxt)-getdep(lst,x);Set.insert(x);
}
void del(int x)
{Set.erase(Set.find(x));if (!Set.size()) return; set<int>::iterator it=Set.lower_bound(x);int nxt,lst;if (it==Set.end()) nxt=*Set.begin(),it--,lst=*it;else if (it==Set.begin()) nxt=*it,lst=*Set.rbegin();else nxt=*it,it--,lst=*it;if (nxt==lst) sum-=getdep(lst,lst)+getdep(x,x)-getdep(x,lst)*2;else sum-=getdep(x,x)+getdep(lst,nxt)-getdep(x,nxt)-getdep(lst,x);
}
signed main()
{n=read(),k=read(),ans=1;for (int i=1,u,v;i<n;i++) u=read(),v=read(),e[u].PB(v),e[v].PB(u);Log[1]=0; for (int i=2;i<=n*2;i++) Log[i]=Log[i>>1]+1;dfs(1,0),Init(),Set.insert(dfn[1]);for (int l=1,r=1;l<n;l++){while (r<n&&sum+1<=k) r++,add(dfn[r]);if (sum+1>k) upmax(ans,r-l);else upmax(ans,r-l+1);del(dfn[l]);}printf("%d\n",ans);return 0;
}

CF372D. Choosing Subtree is Fun相关推荐

  1. CodeForces:372(div1)div373(div2)

    文章目录 前言 CF373A Collecting Beats is Fun Description\text{Description}Description Solution\text{Soluti ...

  2. 吴恩达机器学习笔记55-异常检测算法的特征选择(Choosing What Features to Use of Anomaly Detection)

    吴恩达机器学习笔记55-异常检测算法的特征选择(Choosing What Features to Use of Anomaly Detection) 对于异常检测算法,使用特征是至关重要的,下面谈谈 ...

  3. java git subtree_Git subtree使用

    一.git subtree  与submodule 有类似的作用,可以实现仓内仓,但submodule的子仓是一个链接,subtree是把子仓的copy,类似与新增一个子仓branch .在父仓中几乎 ...

  4. LeetCode 508. Most Frequent Subtree Sum

    原题链接在这里:https://leetcode.com/problems/most-frequent-subtree-sum/description/ 题目: Given the root of a ...

  5. CodeForces - 1324F Maximum White Subtree(树形dp)

    题目链接:点击查看 题目大意:给出 n 个点组成的树,每个点都有一个颜色,非黑即白,现在问对于每个点而言,选出一个连通块,使得白色点的个数与黑色点的个数做差最大 题目分析:记录一下div3的第一次ak ...

  6. F:Maximum White Subtree(树形dp)

    Maximum White Subtree 思路 如果考虑其覆盖范围只会到其子树上,不会到其父节点上的话(假设的情况),这道题就非常好写了,就是一个简单的自底向上传递的树形dpdpdp.所以我们还要考 ...

  7. LeetCode 1516. Move Sub-Tree of N-Ary Tree(DFS)

    文章目录 1. 题目 2. 解题 1. 题目 Given the root of an N-ary tree of unique values, and two nodes of the tree p ...

  8. git subtree 管理项目子模块

    使用场景 当项目越来越庞大之后,不可避免的要拆分成多个子模块,我们希望各个子模块有独立的版本管理,并且由专门的人去维护,这时候我们可以使用git的subtree功能 常用命令 git subtree ...

  9. Educational Codeforces Round 23 E. Choosing The Commander 字典树

    题目连接:E. Choosing The Commander 题意:士兵有个值,指挥官有两个p,l三种操作,第一种添加一个值为p的士兵,第二种删除一个值为p的士兵,(士兵pi只会尊敬pi^p<l ...

最新文章

  1. Elasticsearch-6.7.0系列(六)ES设置集群密码
  2. 什么是编译器,什么是集成开发环境?一文讲明白
  3. jquery --- Poshy Tip jQuery Plugin
  4. 指利用计算机技术实现对文本篇章的理解,行业发展|人工智能的自然语言处理技术已经到了这一步...
  5. C语言中指针的数据类型小结
  6. 最经典25本Python编程开发电子书精粹
  7. QT连接PostSql (小白教程)
  8. TM2013自定义消息记录保存目录
  9. esxi安装威联通_威联通折腾篇三:Virtualization Station 安装虚拟机
  10. 应用密码学:位移密码极简(凯撒密码)
  11. 3大奇葩排序之猴子算法
  12. 图像处理学习笔记之空间滤波(1)图像的噪声
  13. 我的世界热力膨胀JAVA_我的世界热力膨胀MOD矿物类型介绍
  14. java计算出现负数吗,请问一个计算器的有关问题,怎么实现负数计算
  15. More Joel on Software 读书笔记
  16. Android 通过FTP方式下载服务器文件
  17. 黎想深度访谈腾讯顶级产品经理的进阶之路——第五篇《匠心》
  18. PCL中3D点云特征描述与提取(三)
  19. 国内微博客前景黯淡的两个原因
  20. FL Studio 教程之扫弦简介

热门文章

  1. 剑桥大学的下午茶,为何能喝出六十位诺贝尔奖获得者?
  2. “甜橙金融杯”数据建模大赛发布,8万重金寻找大数据金融人才!
  3. 《Pyflink》Flink集群安装,Python+Flink调研
  4. 备赛脱脂经验分享_IEO国际经济学奥林匹克初选宏观备赛经验分享
  5. 放大器非线性失真研究装置_高效布里渊光纤放大器
  6. unity重定向_unity3D游戏开发之动画混合与动画重定向
  7. 表3.5 文章管理测试用例表_本地管理表空间管理机制
  8. java导入导出excel_Java导入导出Excel工具 easyexcel
  9. python中merge函数怎么用_Python Merge函数原理及用法解析
  10. html点击按钮计算两个输入框的和_小程序计算报价功能介绍