7.29 模拟赛总结 平面图欧拉定理

news2024/11/17 1:30:50

复盘

7:40 开题

开题失败,由于前一天有 cf,模拟赛移到下午了

13:45 开题

看 T1,题意很抽象,理清后发现:这直接 dj 不就行了?不会错吧不会错吧,看着 n = 1000 n=1000 n=1000 的数据范围还是不确定,往后看看先

看 T2,以为会了,应该就是个斜率什么的,维护凸包+二分

看 T3 ,隐隐感觉有点眼熟?但一细想又不会左

T4,首先题面比较抽象,但感觉是和以前模拟赛考过的可能有点像,最后看吧

决定先写比较确定的 T2,推了推发现斜率不太好搞,不知道那个是不是单调的,没关系我回分数规划

只用了 O ( 1 ) s O(1)s O(1)s 就写完了,直接过掉了大样例,14:30

决定对拍,发现很快就出错了,调完小错误后仍没过拍,看了看输出发现是精度问题,而且用计算器验证发现是暴力里面由于做除法出错了

最后尝试改 long double,不拍了,先放,已经 15:00 了

回来写 T1,反复审题后笃定 dj 没错,想了想有些细节处理,写写写,细节不少,16:00 才过大样例

时间还多,优势在我,看 T3

发现还是不会,在走廊上胡出了一个 树套数做法,想了想数据范围 5 e 4 5e4 5e4 还觉得很对,但是竟然需要给一个 等腰三角形区域修改操作,做不了做不了,但在这里还是得到了同种数字找区间交、并的想法

回来手玩样例,突然发现这不就是在教我怎么做吗?想了想这个做法,虽然不会证,但构造几组数据都 hack 不掉

17:10 了,决定开写,剩 1h

先用暴力跑出了大样例的答案,更加确信做法是对的,17:45 写完,把 s e t set set 做法和暴力拍了拍

最后二十分钟,看了看 T4,推完样例感觉有思路,编了个 O ( n 6 ) O(n^6) O(n6) 做法,最后细节挺多没写完,遗憾离场

最后 100+95+100+0 = 295 , rk O ( n ) O(\sqrt n) O(n ),还行

感觉 noip 模拟赛还是得抢时间的,难度偏简单的场得快速过简单题,最后去磕难题的高分

ps:T2 挂 5 分不是因为精度,而是有个 ans=0 ,初值赋小了!!

题解

T1

在这里插入图片描述
直接跑 dj,需要快速处理 从某一时刻 t t t 开始,最早的 x x x y y y 同色时间

然后简单讨论一下发现 由于是一整段一整段的,可以直接 O ( 1 ) O(1) O(1) 得到

T2

在这里插入图片描述
应该算是道套路题

化式子,等价于求 S n − S r + S l n − r + l \large\frac{S_n-S_r+S_l}{n-r+l} nr+lSnSr+Sl 最大,由于是分数,我们设 原式 ≤ k \leq k k,二分 k k k,判断是否可以成立

通分得到: S n − n k ≤ ( S r − r k ) − ( S l − l k ) S_n-nk\leq (S_r-rk)-(S_l-lk) Snnk(Srrk)(Sllk),那么我们可以把问题转化:

将原序列中每个数 − k -k k 后,能否找到一段区间使得 区间和 大于等于某一定值?

维护前缀 Min 即可

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 5e5+100 ;

int n , a[N] ;
int Max ;
namespace Part2
{
	const long double eps = 1e-6 ;
	bool check( long double x )
	{
		long double Min = 1e10 , ans = -1e11 , sum = 0 ;
		for(int i = 1 ; i <= n ; i ++ ) {
			sum += a[i]-x ;
			if( i > 1 && i < n ) {
				ans = max( ans , sum-Min ) ; 
			}
			Min = min( Min , sum ) ;
		}
		if( ans >= sum ) return 1 ;
		return 0 ;
	}
	void solve()
	{
		long double l = 0 , r = Max , mid ;
		while( l+eps < r ) {
			mid = (l+r)/2 ;
			if( check(mid) ) {
				r = mid ;
			}
			else {
				l = mid ;
			}
		}
		if( check(l) ) printf("%.3Lf" , l+eps ) ;
		else printf("%.3Lf" , r+eps ) ;
	}
}

int main()
{
	scanf("%d" , &n ) ;
	for(int i = 1 ; i <= n ; i ++ ) {
		scanf("%d" , &a[i] ) ;
		Max = max( Max , a[i] ) ;
	}
	Part2::solve() ;
	return 0 ; 
}

一个小技巧,最后答案 +eps,抹平微小的误差

T3

在这里插入图片描述
首先我们可以发现:对于同种数字来说,区间交是比较 重要的

如果某个数出现过但区间交为空,显然无解

反之第 i i i 个数的交区间 [ L , R ] [L,R] [L,R] 意味着 “ i i i 一定会在这个区间中出现恰好一次”

不妨只考虑比 i i i 大的数对 i i i 的限制,对于一次询问 ( l , r , x ) (l,r,x) (l,r,x) ,可以看作是在区间 [ l , r ] [l,r] [l,r] 中加上 ≥ x \geq x x 的限制

那么求出所有比 i i i 大的数的区间 ,若这个 并 包含了 i i i 的交区间 [ L , R ] [L,R] [L,R],就无解了

反之一定能在并区间外的某个位置把 i i i 给放进去,这样符合所有现有条件

同时在这之后要用 i i i 把区间并更新,那么 i i i 的放置对之后操作也是没有影响的

具体实现,由于要在值域上做,不得不离线了,二分最早矛盾的询问,把这些询问排序后从大到小处理,用 s e t set set 或者 并查集 维护连续段(并区间)

( 然鹅我不会并查集维护连续段

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 1e6+100 , M = 3e4+10 ;

int n , Q ;
struct nn
{
	int l , r , x ;
}a[M] , b[M] ;
bool cmp( nn x , nn y )
{
	return x.x > y.x ;
}
struct node
{
	int l , r ;
	friend bool operator < ( node x , node y ) {
		return x.r < y.r ;
	}
};
set<node> s ;
bool query( int l , int r ) // 查询 [l,r] 是否被包含 
{
	if( s.empty() ) return 0 ;
	auto it = s.lower_bound({0,r}) ;
	if( it != s.end() && it->l <= l ) return 1 ;
	return 0 ;
}
void Insert( int l , int r )
{
	if( s.empty() ) {
		s.insert({l,r}) ;
		return ;
	} 
	int L = l , R = r ;
	auto it = s.lower_bound({0,l-1}) ;
	auto iit = it ;
	for( ; iit != s.end() ; iit ++ ) {
		if( iit->l <= r+1 ) {
			L = min( L , iit->l ) ;
			R = max( R , iit->r ) ;
		}
		else break ;
	}
	s.erase( it , iit ) ;
	s.insert({L,R}) ;
}
bool check( int x ) // 只考虑前 x 次询问 
{
	for(int i = 1 ; i <= x ; i ++ ) b[i] = a[i] ;
	sort( b+1 , b+x+1 , cmp ) ;
	s.clear() ;
	int L = b[1].l , R = b[1].r , lst = 1 ;
	for(int i = 2 ; i <= x ; i ++ ) {
		if( b[i].x == b[i-1].x ) {
			L = max( L , b[i].l ) ;
			R = min( R , b[i].r ) ;
		}
		else { // 处理上一次 
			if( L>R ) return 1 ;// 交集为空,gg 
			if( query(L,R) ) return 1 ; // 被完全覆盖,gg
			for(int j = lst ; j < i ; j ++ ) {
				Insert(b[j].l,b[j].r) ;
			}
			lst = i , L = b[i].l , R = b[i].r ;
		}
	}
	if( L>R ) return 1 ;
	if( query(L,R) ) return 1 ;
	return 0 ;
}

int main()
{
	scanf("%d%d" , &n , &Q ) ;
	for(int i = 1 ; i <= Q ; i ++ ) {
		scanf("%d%d%d" , &a[i].l , &a[i].r , &a[i].x ) ;
	}
	int l = 1 , r = Q , mid ;
	while( l+1 < r ) {
		mid = (l+r)>>1 ;
		if( check(mid) ) {
			r = mid ;
		}
		else {
			l = mid ;
		}
	}
	if( check(l) ) printf("%d" , l ) ;
	else if( check(r) ) printf("%d" , r ) ;
	else printf("0") ; 
	return 0 ; 
}

T4


(又臭又长的题面

通过手玩样例,我们可以得到猜到一个做法:

从小到大加入新点,每次看新加入的点能不能连出来一个新的 “山谷”,如果能加到答案里

这样做很对

接下来唯一的问题是怎么判断 连通形成的新山谷没有“洞”

一个 trick:平面图的欧拉定理

在这里插入图片描述
边不交叉!

V V V 为点数, E E E 为边数, F F F 为面数(指的是被边分割成的区域个数),欧拉定理为:

这张平面图连通的等价条件是 V − E + F = 2 V-E+F=2 VE+F=2

推论:

一张平面图的连通块数 C C C 可以这么计算: V − E + F = C + 1 V-E+F=C+1 VE+F=C+1

经常用在网格图中,把 染色点 看作点,相邻点对(四联通) 看作边

此时 F F F 为 4相邻块数 + 空腔块数 + 1

在这里插入图片描述
来说说本题怎么用

考虑对于一个连通块,怎么 c h e c k check check

洞可以看作是一个环,且不是由四相邻的点构成

那么合并过程中维护出 连通块的 点数 V V V,相邻对数 E E E,四相邻对数 F F F

然后只需 c h e c k check check 是否有: V − E + F + 1 = 2 V-E+F+1=2 VE+F+1=2,意思就是没有其它的环,即空腔

代码很好写

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 760 ;
// 从低到高加点,只需判是否有洞 
// 利用平面图欧拉定理判环 
 
int n , h[N][N] ;
struct nn
{
	int x , y , h ;
}a[N*N] ;
int len ;
bool cmp ( nn x , nn y )
{
	if( x.h^y.h ) return x.h<y.h ;
	if( x.x^y.x ) return x.x<y.x ;
	return x.y<y.y ;
}
int bin[N*N] , V[N*N] , E[N*N] , F[N*N] ; 
inline int get( int x , int y )
{
	return (x-1)*n+y ;
}
int Find( int x )
{
	if( x == bin[x] ) return x ;
	return bin[x] = Find(bin[x]) ;
}
int dx[4] = {0,0,1,-1} ;
int dy[4] = {1,-1,0,0} ;
bool vis[N][N] ;
inline int T ( int x , int y )
{
	return (vis[x][y]&&vis[x-1][y]&&vis[x-1][y-1]&&vis[x][y-1])+
		   (vis[x][y]&&vis[x-1][y]&&vis[x][y+1]&&vis[x-1][y+1])+
		   (vis[x][y]&&vis[x+1][y]&&vis[x+1][y-1]&&vis[x][y-1])+
		   (vis[x][y]&&vis[x+1][y]&&vis[x+1][y+1]&&vis[x][y+1]) ; 
}

int main()
{
	scanf("%d" , &n ) ;
	for(int i = 1 ; i <= n ; i ++ ) {
		for(int j = 1 ; j <= n ; j ++ ) {
			scanf("%d" , &h[i][j] ) ;
			a[++len] = (nn){i,j,h[i][j]} ;
			bin[get(i,j)] = get(i,j) ;
		}
	}
	sort( a+1 , a+len+1 , cmp ) ;
	LL ans = 0 ;
	for(int i = 1 ; i <= len ; i ++ ) {
		int x = a[i].x , y = a[i].y ;
		int ne = 0 , nv = 1 ;
		for(int j = 0 ; j < 4 ; j ++ ) {
			int tx=x+dx[j] , ty=y+dy[j] ;
			if( tx<1||tx>n||ty<1||ty>n ) continue ;
			if( !vis[tx][ty] ) continue ;
			int fx = Find(get(tx,ty)) ;
			if( fx != get(x,y) ) {
				V[get(x,y)] += V[fx] , E[get(x,y)] += E[fx] , F[get(x,y)] += F[fx] ;
				bin[fx] = get(x,y) ;
			}
			ne ++ ;
		}
		vis[x][y] = 1 ;
		E[get(x,y)] += ne ; V[get(x,y)] += nv ; F[get(x,y)] += T(x,y) ;
		if( V[get(x,y)]-E[get(x,y)]+F[get(x,y)]+1 == 2 ) { // 没有除四联通以外的环 
			ans += V[get(x,y)] ;
		}
	}
	printf("%lld" , ans ) ;
	return 0 ; 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java实现权重轮询算法

package com.example.demo.demos.web.nginx;import java.util.ArrayList; import java.util.List;public class WeightedRoundRobin {private static List<Server> servers new ArrayList<>(); // 存储服务器的列表private static int currentIndex -1; // 当前服…

APP测试基本流程以及APP测试要点梳理,成功入职就靠它了

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

【MATLAB源码-第161期】基于matlab的OQPSK系统仿真,输出误码率曲线图,眼图以及各节点信号图像对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交四相移相键控&#xff08;OQPSK&#xff0c;Orthogonal Quadrature Phase Shift Keying&#xff09;是一种数字调制技术&#xff0c;它在传统的QPSK&#xff08;Quadrature Phase Shift Keying&#xff0c;四相移相键控&…

Linux--序列化与反序列化

序列化 序列化是指将数据结构或对象状态转换成可以存储或传输的格式的过程。在序列化过程中&#xff0c;对象的状态信息被转换为可以保持或传输的格式&#xff08;如二进制、XML、JSON等&#xff09;。序列化后的数据可以被写入到文件、数据库、内存缓冲区中&#xff0c;或者通…

jupyter notebook报错: No module named ‘pandas‘

打开jupyter notebook&#xff0c;新建Python3&#xff0c;编写代码import pandas as pd jupyter notebook: No module named pandas 解决办法 :打开Anaconda prompt&#xff0c;输入pip install pandas,安装时可能因为网速原因失败&#xff0c;用同样的命令再试一次&#xf…

数据透视表(二)

文章目录 导入外部数据源创建数据透视表Query 工具下的数据透视表创建如何统计业绩成交情况创建组利用函数构建辅助列创建组手动创建多样分组创建组区间统计创建组按年月日统计数据透视表的多种统计方法计算字段 导入外部数据源创建数据透视表 点击数据选项卡下数据-获取外部数…

04.FreeRTOS任务创建

04. FreeRTOS任务创建与任务删除 1. FreeRTOS创建和删除任务相关API函数 函数描述xTaskCreate()动态方式创建任务xTaskCreateStatic()静态方式创建任务xTaskCreateRestricted()动态方式创建使用 MPU 限制的任务xTaskCreateRestrictedStatic()静态方式创建使用 MPU 限制的任务…

js_拳皇(下)

文章目录 架构设计视频演示碰撞检测碰撞检测函数 构想血条和计时器全屏后续工作 架构设计 一图胜千言 #mermaid-svg-erOUDyAO5t0XgYyU {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-erOUDyAO5t0XgYyU .error-icon{…

塞尔维亚皇家科学与艺术学院向迪科维奇将军颁发奖章

2015 年 6 月 28 日&#xff0c;在托波拉文化中心礼堂&#xff0c;由塞尔维亚皇家科学家与艺术学院&#xff08;SKANU&#xff09;组织举行了一场颁奖仪式&#xff0c;向过去一年里为科学院做出无私贡献的杰出个人和集体表示感谢。 经塞尔维亚皇家科学与艺术学院一致决定&#…

RWKV 社区近期有哪些学术研究进展?

2024 年 5 月 7 日&#xff0c;我们呼吁大家使用 RWKV-6 替代 Mamba 进行科研。截至 7 月 29 日&#xff0c;来自全球各地的科研团队已经陆续发表了 7 篇基于 RWKV 架构、在各个领域进行深入研究的论文。 新的 RWKV 学术研究主要聚焦于具身智能、图像处理、模型架构三个方面。…

[Windows] 简单易用的图片去水印工具,Inpaint 9.1 单文件版

很多软件都有这个功能&#xff0c;但这个算法非常自然&#xff0c;软件小巧。 而且极为简单&#xff0c;涂鸦笔一抹&#xff0c;点绿色的《处理图像》 &#xff0c;一秒完成。 我从它6.0的版本一直用过来。现在这个是9.1 发现论坛里的 都是几年前的&#xff0c;全部都失效了。 …

【策略工厂模式】记录策略工厂模式简单实现

策略工厂模式 1. 需求背景2. 代码实现2.1 定义基类接口2.2 排序策略接口定义2.3 定义抽象类&#xff0c;实现策略接口2.4 具体的排序策略实现类2.5 实现策略工厂类2.6 控制类 3. 启动测试4. 总结 1. 需求背景 现在需要你创建一个策略工厂类&#xff0c;来根据策略实现各种排序…

达梦数据库的系统视图v$buffer_lru_first

达梦数据库的系统视图v$buffer_lru_first 达梦数据库系统视图V$BUFFER_LRU_FIRST的主要作用是显示所有缓冲区LRU链首页信息。这个视图帮助数据库管理员监控和管理缓冲池中LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;链的性能&#xff0c;通过查看…

专业级享受:2024年视频剪辑工具深度评测与推荐

说到视屏剪辑很多人都会想要到剪映吧&#xff0c;那剪映怎么剪辑视屏呢&#xff1f;剪映之外还有没有其他好用到视屏剪辑软件呢&#xff1f;这次就分享一些我自己用过到工具吧。 1.福昕视频编辑 链接直达>>https://www.pdf365.cn/foxit-clip/ 这个视频剪辑软件大大的…

【Stable Diffusion】(基础篇六)—— embedding

embedding 本系列博客笔记主要参考B站nenly同学的视频教程&#xff0c;传送门&#xff1a;B站第一套系统的AI绘画课&#xff01;零基础学会Stable Diffusion&#xff0c;这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 除了大模型和VAE之外…

普明服务小程序正式招募合伙人,共绘家政保洁行业新蓝图

随着家政保洁行业的快速发展和消费者对高品质服务需求的日益增长&#xff0c;普明服务小程序凭借其专业、高效、便捷的服务体验&#xff0c;迅速在市场上崭露头角。为了进一步拓展业务&#xff0c;提升品牌影响力&#xff0c;普明服务小程序现正式面向社会招募合伙人&#xff0…

你还在为PDF转Word烦恼?试试这四款免费工具吧!

悄咪咪问一句&#xff0c;大家在平时上班时最头疼的事情有哪些&#xff1f;我想会有很多朋友也有pdf如何在线转换word文档的免费方式&#xff0c;毕竟这些办公文档是非常常见的问题了&#xff0c;所以今天就专门准备这么一篇文章来分享我个人喜欢的四款好用工具&#xff1a; 第…

基于ChatGPT的“看图说话”

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

dockerd --debugr排查服务无法启动的异常

1、查看docker服务运行状态 [rootlocalhost ~]# systemctl status docker 2、使用dockerd --debug排查错误 [rootlocalhost ~]# dockerd --debug 3、使用dockerd --debug获取的错误 4、根错误在网上查找解决方法 上图错误为二进制安装docker服务&#xff0c;/usr/local/bin/…

从里到外刨析一台电脑的性能,认识电脑很重要,妈妈再也不用担心我买电脑被骗了

现如今时代随着技术的发展&#xff0c;骗子的手段也越来越高明&#xff0c;因此从里到外刨析一台电脑的性能&#xff0c;认识电脑很重要&#xff0c;特别是准备购买电脑的小伙伴&#xff0c;建议看完这篇文章&#xff0c;其他听别人说电脑的好坏都是虚的&#xff0c;只有自己真…