CodeForces - 566D

这题虽然是模板题,但是还是要借助区间优化来实现段落的合并,因为数据量实在是太大了,很容易超时。

如果不加的朴素做法就是:

//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

这里有一个注意点需要引起重视:CodeForces - 566D_第1张图片

优化算法的核心如果改成这样就会出错,虽然我还不知道具体的错误数据,但是大概推测一下原因,可能是:

如果是这样改的话,[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

 

你可能感兴趣的:(CodeForces - 566D)