关于D1T1的一个假做法
  • 板块学术版
  • 楼主loser_seele
  • 当前回复19
  • 已保存回复19
  • 发布时间2023/4/1 14:37
  • 上次更新2023/10/23 19:48:23
查看原帖
关于D1T1的一个假做法
714821
loser_seele楼主2023/4/1 14:37

RT,大概的做法是不断暴力合并区间,具体实现看代码。

这么做没算错的话最差应该是 m 方的,但是大样例跑得飞快。有无正确复杂度证明或者 hack 数据。

#include <bits/stdc++.h>
using namespace std;
inline int read()
{
	int now=0;
	char ch=getchar();
	while(!isdigit(ch))
	ch=getchar();
	while(isdigit(ch))
	now=now*10+ch-'0',ch=getchar();
	return now;
}
vector<int>ans;
const int maxn=2e6+10;
int l[maxn],r[maxn],n,m,x;
bool vis[maxn];
int query_merge(int l1,int l2,int r1,int r2)
{
	return (min(r1,r2)-max(l1,l2)>=0);
}
int vis2[maxn];
void add(int k)
{
		if(k==x)
		return;
	if(!vis2[k])
	ans.push_back(k),vis2[k]=1;
}
void calc_left()
{
	bool ok=1;
	int nowl=x,nowr=x;
	while(ok)
	{
		ok=0;
		for(int i=1;i<=m;i++)
		if(!vis[i])
		{
			if(query_merge(nowl,l[i],nowr,r[i]))
			nowl=min(nowl,l[i]),add(l[i]),vis[i]=1,ok=1;
		}
	}
}
void calc_right()
{
	memset(vis,0,sizeof vis);
	bool ok=1;
	int nowl=x,nowr=x;
	while(ok)
	{
		ok=0;
		for(int i=1;i<=m;i++)
		if(!vis[i])
		{
			if(query_merge(nowl,l[i],nowr,r[i]))
			nowr=max(nowr,r[i]),add(r[i]),vis[i]=1,ok=1;
		}
	}
}
main()
{
		freopen("station.in","r",stdin);
		freopen("station.out","w",stdout);
	n=read(),m=read(),x=read();
	for(int i=1;i<=m;i++)
	l[i]=read(),r[i]=read();
	calc_left();
	calc_right();
	sort(ans.begin(),ans.end());
	for(auto x:ans)
	cout<<x<<' ';
}
/*
7 5 4
3 4
4 6
1 3
5 7
4 6
*/

2023/4/1 14:37
加载中...