首页 > 其他分享 >P8125 [BalticOI 2021 Day2] The short shank 题解

P8125 [BalticOI 2021 Day2] The short shank 题解

时间:2024-06-05 11:46:51浏览次数:30  
标签:short shank int 题解 top lst MAXN now mx

首先会发现若 \(t_i <= T\) 的话那么他最终一定会造反。

我们只考虑 \(t_i >T\) 的情况。设 \(lst_i\) 表示 \(i\) 左边第一个可以影响(使他造反)到 \(i\) 的位置,那么我们一定要在 \([lst_i,i]\) 这个区间中的某一个位置放上床垫才能使 \(i\) 不造反。

这样有一个 \(O(nd)\) 的 dp,但是复杂度显然会炸。考虑挖掘一些性质,会发现所有区间都是包含或者不交的。证明也比较简单,若两个区间有交,即 \(i<j,lsti \le lst_j \le i\),那么 \(lst_j\) 这个位置也一定能影响到 \(i\),矛盾。所以任意两个区间都不交叉。

那么我们按照区间的包含关系建图,就变成一个森林。考虑转化题意,若在叶子节点的区间中放一个床垫,那么它到根节点的路径上的所有点都不会造反了。所以题意转化为求 \(d\) 条不相交的链,使得这些链的总长度最大。直接长链剖分,然后取前 \(d\) 长的链即可。

求 \(lst\) 数组以及连边都可以用单调栈维护,最终求前 \(d\) 长链可以用优先队列维护,时间复杂度 \(O(n+d \log n)\)。

关于取前 \(d\) 长的链的证明:对于两条不是最长链的链,我们都可以把它换成最长链加另外一条链,这样总长度一定不劣(画个图更容易理解)。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
int n,d,T,t[MAXN],lst[MAXN],ans,fa[MAXN];
int head[MAXN],cnt,depth[MAXN],son[MAXN],mx[MAXN];
struct Node {int u,v,nxt;}e[MAXN << 1];
void Add(int u,int v) {e[++cnt] = {u,v,head[u]};head[u] = cnt;}
priority_queue <int,vector <int>,less <int> > q;
void dfs(int u,int father) {
	depth[u] = depth[father] + 1,mx[u] = depth[u];
	for(int i = head[u]; ~ i;i = e[i].nxt) {
		int now = e[i].v;
		if(now == father) continue;
		dfs(now,u),mx[u] = max(mx[u],mx[now]);
		if(mx[now] > mx[son[u]]) son[u] = now;
	}
} void sdfs(int u,int father,int len) {
	if(son[u] == 0) return q.push(len);
	sdfs(son[u],u,len + 1);
	for(int i = head[u]; ~ i;i = e[i].nxt) 
		if(e[i].v != father && e[i].v != son[u]) sdfs(e[i].v,u,1);
} stack <int> s;
signed main() {
	memset(head,-1,sizeof head);
	cin >> n >> d >> T;
	for(int i = 1;i <= n;i++) cin >> t[i];
	for(int i = 1;i <= n;i++) 
		if(t[i] > T) {
			while(s.size() && t[s.top()] + i - s.top() > T) s.pop(); 
			if(s.size()) lst[i] = s.top();
		} else {
			while(s.size() && t[s.top()] + i - s.top() >= t[i]) s.pop(); 
			s.push(i);
		}
	while(!s.empty()) s.pop();
	for(int i = n;i >= 1;i--) {
		if(lst[i] == 0) continue;
		while(!s.empty() && lst[s.top()] > lst[i]) s.pop();
		if(!s.empty()) Add(s.top(),i),fa[i] = s.top();
		s.push(i); 
	} for(int i = 1;i <= n;i++) {
		if(t[i] <= T) continue;
		if(lst[i] == 0) ans++;
		else if(fa[i] == 0) dfs(i,0),sdfs(i,0,1);
	} while(d > 0 && !q.empty()) 
		ans += q.top(),q.pop(),d--; 
	cout << n - ans;
	return 0;
} 

标签:short,shank,int,题解,top,lst,MAXN,now,mx
From: https://www.cnblogs.com/Creeperl/p/18232680

相关文章

  • 2024年03月 GESP等级认证Python编程(一级)试题解析
    【单选题】(每题2分)1、小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是?()A、小程序   B、计时器   C、操作系统   D、神话人物   正确答案:C2、中国计算机学会(CCF)在2024年1月27日的颁奖典礼上颁布了王选奖,王选先生的重大贡献是?()A、制......
  • Codeforces Round 950 (Div. 3)个人题解(A~F1)
    CodeforcesRound950(Div.3)个人题解(A~F1)题解火车头#define_CRT_SECURE_NO_WARNINGS1#include<iostream>#include<vector>#include<algorithm>#include<set>#include<unordered_map>#include<cstring>#include<cstdio&......
  • 按按钮题解
    按按钮题解在量体温,打不了代码,来写题解。赞美lwq,三句话让我跟上了课堂节奏。题意数轴\(n\)个按钮,第\(i\)个按钮在坐标\(i\)。有\(m\)次询问,\(i\)询问为在时刻\(t_i\)按下\(b_i\)。可以在时刻\(0\)安排一些机器人,机器人可以花\(1\)单位时间向左或右移动\(1\)......
  • acwing329 围栏障碍训练场 题解
    考试压轴题,意识到这题是线段树优化\(dp\)时追悔莫及。为了简化题目,我将从起点到原点变成了从原点到起点(这样就可以省去两个数组的空间)。想到设\(dp_{i,j}\)表示在第\(i\)层,奶牛们在\(j\)列时的最小移动范围,则转移方程为(设输入为\(l,r\)):\[\begin{cases}dp_{i,j}=dp_{......
  • 会前会后系统Q&A:董事会管理工具相关问题解答
    不同企业在购买董事会管理工具时,都会带有不同的功能需求,希望能够借此提升本企业的董事会管理效率和质量。作为垂直领域的专业SaaS工具,会前会后针对董事会的工作流程研发,符合董事会成员的使用系统,在董事履职、董事会管理中提供颇多助力。下面是关于会前会后系统董事会管理工具......
  • Codeforces Round 949 (Div. 2) 中文题解
    A对于一个特定的\(x\),Piggy总是会选择\(p\)使得\(p\)是质数,所以分数就是\(x\)的质因子个数。容易发现至少有\(t\)个质因子的数是\(2^t\)。最大的满足\(2^t\ler\)的整数\(t\)是\(\left\lfloor\log_2r\right\rfloor\)。又因为\(2l\ler\),所以\(\log_2l+......
  • gpt4free软件的 g4f gui 网页速度非常慢的问题解决
    问题:g4f gui启动网页很难连上gpt4free是一个为大众提供的Openai等大模型API调用服务的软件,但是在装好启动g4f gui,使用8080端口连接后,发现网页一直在执行,半天还没好。怀疑是网页里面的一些js加载有问题。通过在python命令行使用importg4f;g4f.version命令来找到g4f的......
  • MySQL数据库:Lock wait timeout exceeded; try restarting transaction问题解析及解决方
    MySQL数据库:Lockwaittimeoutexceeded;tryrestartingtransaction问题解析及解决方案一、背景描述二、原因分析三、解决方案3.1方案一事务信息查询3.2方案二如果杀掉线程依然不能解决,可以查找执行线程耗时比较久的任务,kill掉3.3方案三innodb_lock_wait_timeout锁定等......
  • (第25天)【leetcode题解】二叉树的层序遍历
    目录429、N叉树的层序遍历题目描述思路代码515、在每个树行中找最大值题目描述思路代码116、填充每个节点的下一个右侧节点指针题目描述思路代码117、填充每个节点的下一个右侧节点指针II题目描述思路代码104、二叉树的最大深度题目描述思路代码111、二叉树的最小深......
  • 2009年408真题解析
    2009年408真题解析【2009.1】为解决计算机主机与打印机之间速度不匹配问题,通常设置一个打印数据缓冲区,主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。该缓冲区的逻辑结构应该是。A.栈B.队列C.树D.图【知识点】栈和队列特点及应用。【答案】B......