「CF1710D」Recover the Tree

「CF1710D」Recover the Tree

Solution

考虑好区间 I1,I2(I1I2)I1I2I1I2 都是好区间。于是我们考虑从长度小开始构建。

初始时我们把 n 个点看作 n 个连通分量,设 [lvi,rvi] 表示点 i 所属连通分量的区间。

枚举到区间 [L,R] 时,如果 [L,R] 不连通或 [L,R] 已经连通则不考虑。否则我们需要将 L 所属连通分量和 R 所属连通分量含有 [L,R] 中不属于两个连通分量的部分连通。我们可以考虑如下连通方案。设 [L,R]k+2 个连通分量组成,分别为 [l0,r0],[l1,r1],,[lk+1,rk+1],同时设 x[l0,r0],y[lk+1,rk+1]。连接方式如下

l2kl4l2xyl1l3l2k+1

即为下图

Code

点击查看代码
#include<bits/stdc++.h>
#define MOD (1000000007)
#define ll long long
#define MAXN (2005)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(x) (x&-x)
#define Swap(x,y) (x^=y,y^=x,x^=y)
using namespace std;
void read(ll &x)
{
	register char ch=0;register bool f=0;x=0;
	while(ch<'0'||ch>'9'){f|=!(ch^'-');ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	x=f?-x:x;
}
void read(int &x)
{
	register char ch=0;register bool f=0;x=0;
	while(ch<'0'||ch>'9'){f|=!(ch^'-');ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	x=f?-x:x;
}
void write(ll x,bool bk)
{
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	if(!x)
	{
		if(!bk) putchar('0');
		return;
	}
	write(x/10,1);
	putchar((x%10)^48);
}
void print(ll x,char ch)
{
	write(x,0);
	if(ch) putchar(ch);
}
struct out{
    ll x,y;
};
vector<out> ans;
int n;
int res[MAXN][MAXN],lv[MAXN],rv[MAXN];
char g[MAXN][MAXN];
void solve()
{
	ans.clear();
    read(n);
    for(int i=1;i<=n;i++)
    {
        lv[i]=i,rv[i]=i;
        scanf("%s",g[i]+i);
    }
	for(int len=2;len<=n;len++)
	{
		for(int l=1;l<=n-len+1;l++)
		{
			int r=l+len-1;
			if((!(g[l][r]^'1'))&&(lv[l]^rv[r])&&(rv[l]^rv[r]))
			{
				ans.push_back((out){l,r});
				vector<int> tmp[2];
				int id=1;
				tmp[0].push_back(l);
				tmp[1].push_back(r);
				for(int i=rv[l]+1;i<lv[r];i++)
				{
					if(!(lv[i]^i))
					{
						ans.push_back((out){tmp[id].back(),i});
						tmp[id].push_back(i);
						id^=1;
					}
				}
				int L=lv[l],R=rv[r];
				for(int i=L;i<=R;i++)
				{
					lv[i]=L;
					rv[i]=R;
				}
			}
		}
	}
	for(auto x:ans)
		print(x.x,' '),print(x.y,'\n');
	return;
}
int T;
int main()
{
    // freopen("data.in","r",stdin);
    // freopen("data.out","w",stdout);
	read(T);
	while(T--) solve();
	return 0;
}

作者:littlepinkpig

出处:https://www.cnblogs.com/littlepinkpig/p/16793939.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

你可以在这里自定义其他内容

作者:littlepinkpig

出处:https://www.cnblogs.com/littlepinkpig/p/16793939.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   little_pinkpig  阅读(123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
more_horiz
keyboard_arrow_up light_mode palette
选择主题