私たちはシーケンスが大好きです(そしてチェックセット)

AngryBaconはシーケンスがとても好きで、シーケンスに関連するすべてのものが好きです。

AngryBaconの前に長さNのシーケンスがあり、各要素はMを超えない正の整数です。
AngryBaconはQマジックを使用します。マジックの内容が、Mを超えない正の整数a、bのペアであるたびに、aであるシーケンス内のすべての数値がbとして書き換えられることを意味します。
AngryBaconは、彼の最愛のシーケンスが最終的にどうなるかを知りたがっていました。

Inputの
最初の行には、3つの整数N、M、およびQが含まれています。意味は上記のとおりです。
2行目には、初期シーケンスを表すn個の整数が含まれています。次の行Qでは、各行に2つの整数a、bがあります。

出力
は、最終シーケンスの形状を示すN個の整数を含む1行を出力します。

サンプル
入力コピー55
3
1 2 3 4 5
3 1
4 3
15
出力52
5
35ヒント
[データ範囲]

データの20%の場合:1≤n、m、Q≤1000。
100のデータの場合:1≤n、m、Q≤1000000、1≤a、b、Ai≤M。
出典
ShiguangMiddle School 2017 Changle Summer Camp No. 7

意味: 理解できるはずです。
解決策: マージ検索の使用を考えるのは難しいことではありませんが、毎回新しいものに置き換える
ことを考えるのは難しいです。この
1-> 2
2-> 3
5-> 1のように、
かどうかを区別するのは簡単ではありません。 1は新しく生成されたものか元のもの
であるため、維持するために新しい配列が必要です。

/// a [x] = iは、数値xの最も早い点がiに現れることを意味します。
実際、ある数値が別の数値に変更されるたびに、それは全身に影響を与える種類の動きです。全身を動かすと、時間計算量が非常に大きくなるので、代表を見つけて、この代表だけを使ってこのタイプの数字を表します。このタイプの数字が変わる場合は、この数字を変えるだけです。
実際、その番号の最も早い位置を維持し、交換されるたびに最初の番号を交換することです。

高速読み取りを使用してください。scanfでタイムアウトしました。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+7;

int dis[maxn],vis[maxn];
int a[maxn];
int f(int x){
    
    
    if(dis[x]==x) return x;
    return dis[x]=f(dis[x]);
}
int read()
{
    
    
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {
    
    if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
int main(){
    
    
    int n,m,p;
    n=read();m=read();p=read();
    ///scanf("%lld%lld%lld",&n,&m,&p);
    for(int i=1;i<=n;i++) dis[i]=i;
    for(int i=1;i<=n;i++){
    
    
        int x;
        x=read();
        ///a[x]=i 表示x这个数出现最早点在i 
        ///vis[i]=x 表示i点上放的是x
        if(!a[x]) a[x]=i,vis[i]=x;///没动过 找到第一个节点
        else dis[i]=f(a[x]);
        ///找到第一次出现的位置
    }
    while(p--){
    
    
        int x,y;
        x=read();y=read();
        ///找到第一次出现的地方
        if(a[x]){
    
    
            int tmp=a[x];
            a[x]=0;
            ///找的这个,因为全部替换这个数就不会存在在序列中清零
            ///存在,就比较最靠前的是替换的靠前还是原本的,把他们连起来
            if(a[y])dis[f(tmp)]=f(a[y]);
            else a[y]=tmp,vis[tmp]=y;
             ///不存在b直接把a换成b不用比较 那么s数组放的值也会变化
        }
    }
    for(int i=1;i<=n;i++){
    
    
        printf("%d ",vis[f(i)]);///最后一次变成了什么
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_45911397/article/details/110449145