这题虽然是模板题,但是还是要借助区间优化来实现段落的合并,因为数据量实在是太大了,很容易超时。
如果不加的朴素做法就是:
//C
#include
#include
#include
using namespace std;
#define MAXN 200010
int Pre[MAXN],Next[MAXN];
void Init(int n)
{
int i;
for(i=1;i<=n;i++)
{
Pre[i]=i;
Next[i]=i+1;
}
}
int Find(int x)
{
if(Pre[x]!=x)
Pre[x]=Find(Pre[x]);
return Pre[x];
}
void Union1(int x,int y)
{
x=Find(x);
y=Find(y);
if(x==y)
return;
Pre[x]=y;
}
int main()
{
int i;
int n,q;
int type,x,y;
int temp;
while(scanf("%d%d",&n,&q)!=EOF)
{
Init(n);
while(q--)
{
scanf("%d%d%d",&type,&x,&y);
if(type==1)
Union1(x,y);
else if(type==2)
{
if(x>y)
swap(x,y);
for(i=x+1;i<=y;i++)
{
Union1(i-1,i);
//temp=Next[i];
//Next[i]=Next[y];
}
}
else
{
x=Find(x);
y=Find(y);
if(x==y)
printf("%s\n","YES");
else
printf("%s\n","NO");
}
}
}
return 0;
}
但是会超时。。。
所以还是优化一下吧。
至于关于路径优化的Rank[ ]可加可不加(虽然不知道原因,但是一般的题目的题解好像很少看到路径优化的)。
参考博客:
https://blog.csdn.net/jay__bryant/article/details/81413167
优化算法的核心如果改成这样就会出错,虽然我还不知道具体的错误数据,但是大概推测一下原因,可能是:
如果是这样改的话,[x,y]的所有元素都会指向Next[y],正确代码的是[x+1,y]会全部指向Next[y],而x会指向x+1,是唯一的区别,但是错误原因不详。。。。。。
记住吧,可能是区间合并的优化的套路。。。。
代码:
//C
#include
#include
#include
using namespace std;
#define MAXN 200010
int Pre[MAXN],Next[MAXN];
void Init(int n)
{
int i;
for(i=1;i<=n;i++)
{
Pre[i]=i;
Next[i]=i+1;
}
}
int Find(int x)
{
if(Pre[x]!=x)
Pre[x]=Find(Pre[x]);
return Pre[x];
}
void Union1(int x,int y)
{
x=Find(x);
y=Find(y);
if(x==y)
return;
Pre[x]=y;
}
int main()
{
int i;
int n,q;
int type,x,y;
int temp;
while(scanf("%d%d",&n,&q)!=EOF)
{
Init(n);
while(q--)
{
scanf("%d%d%d",&type,&x,&y);
if(type==1)
Union1(x,y);
else if(type==2)
{
if(x>y)
swap(x,y);
for(i=x;i