銀河英雄のNOI 2002の伝説

P1196銀河英雄ロス・バレーの[NOI2002]伝説

羅区ポータル

1521 JDOJ:銀河英雄伝説VIJOS-P1443

JDOJポータル

説明

AD Wuba○年、地球の住民は、第2遊星に牡牛座のαを移行し、宇宙の暦年のための同じ年の治世のタイトルであっ設立された銀河連邦の宣言を発表し、銀河の深さに拡大し始めました。宇宙暦1799年、天の川の星のフィールドBami LEEN戦争で2軍圏。グループ加学校宇宙提督ラインハルトは3万の指揮下に敵の軍艦を満たしていますヤンWeili組織という名前の大胆なグループの完全オフに設定10万船、より導きました。ヤンWeili良い地層、少ないと勝つための戦術の様々な頻繁に巧妙な使用は、必然的に生の傲慢さを喜ばします。この戦いでは、彼はBamiリーンスターフィールドの戦場は、それぞれ1、2、...、30,000番30,000列に分割されます。その後、彼は彼の軍艦はまた、2、1の番号が付けられて...、30000、i行目の私が聞かせて番号が軍艦(I = 1、2、...、30000)、「単語ハイドラ配列」、誘惑を形成するために置きます深さの敵。これは最初のラインナップです。侵略敵が到着すると、ヤンWeiliは、船のほとんどは、いくつかの列に焦点を当て、集中的な攻撃の実装をいくつかの命令を発行したマージされます。i番目の船は、全体として尾(ヘッドの先端が後)j番目のキュー船船に接続されている全船キューを意味し、M ijのために命令をマージします。明らかに軍艦を構成同じ列にある1つまたは複数によってキューを軍艦。命令実行キューの組み合わせ結果は増加します。しかし、狡猾なラインハルトは、戦略的な取り組みをしていました。戦闘では、彼はいつでも広大なインテリジェンスネットワークを動員ヤンWeili艦隊の指示に耳を傾けることができます。ヤンWeiliが艦隊を動員する命令を発行している間、電流分布ヤンWeiliの後れを取らないために、ラインハルトの軍艦は、いくつかの照会コマンドを発行します:C IJ。ディレクティブは、意味同じ列に、そしてそれらの間でどのように多くの軍艦に配置された場合、現在は同じ列にコンピュータ、ヤンWeili番号iとj番目の戦艦の戦艦をお願いします。ベテランの先輩プログラマとして、あなたがプログラム解析ヤンWeili命令を書き込み、問い合わせラインハルトに答えるように求められます。最後の戦いが始まった、銀河の歴史はページを回した......

入力

入力整数の最初のラインT(1 <= T <= 500,000)、Tは、命令の総数を表します。Tは各行が一つの命令を有する、次の行を有します。2つの命令の形式がある:1.M ijは:iおよびjは、2つの整数(1 <= iは、J <= 30000)、命令数に応じ軍艦を表しています。命令は、ラインハルトはヤンWeiliリリースを盗聴艦隊コマンドを動員し、そしてなく、同じ列内のi番目とj番目の戦艦の戦艦を確保することです。2.C IJ:i、jは番号が軍艦を表す指示に応じて二つの整数(1 <= I、J <= 30000)です。この命令は、ラインハルトの挑戦発行される命令です。

出力

あなたのプログラムは、分析および治療のために、各命令の入力をオンにする必要があります:艦隊はヤンWeili命令が発行され、動員された場合、それは艦隊の配置が変更されたことを意味し、あなたのプログラムはこれを気づいたが、任意の情報を印刷しません。もしラインハルトは、命令を出し、あなたのプログラムが出力1行は、同じ列に船の数、i番目とj番目の戦艦の戦艦との配置を表す整数が含まれていなければならない課題です。同じ列に現在のi番目とj番目の船の船でない場合は、-1が出力されます。

サンプル入力

4 M 2 C 1 2 M 2 4 C 4 2

サンプル出力

-1 1

ソリューション:

私はこのトピックを読んで興奮しています。

チェックし、設定する権利を持つ良い質問を(私は毎年たい水缶NOIので)

いわゆる加重互いに素-セットは互いに素セットの加重値であり、我々はそれを処理して、重みを下にスライドさせたときに処理し、コレクションをチェックする必要があります。

この質問では、我々はイタリアの2つの操作が合併持っていたことが判明し、クエリの場合、クエリは二つの要素の同じセットからのものです、我々は次の操作を得たことを、この距離はポイントのこの質問は非常に困難であることがわかりました。この距離合併前に(キューの先頭からこの時点までの前処理として実施するので、最後の二つを差し引いた後は、キューの先頭からの距離がマイナスA)(独自の描画軸を信じてはいけません)。

ここでも、読んで注意してください。

コード:

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int fa[30001],dist[30001],sum[30001],t;//dist数组表示点到队首的距离,sum数组表示这个队中一共有多少个元素。
int find(int x)
{                                       
    if(fa[x]==x)
        return x;     
    int fx=find(fa[x]);                            
    dist[x]+=dist[fa[x]]; //累加dist                     
    return fa[x]=fx;
}//路径压缩的并查集查询操作
int main()
{
    scanf("%d",&t);
    for(int i=1;i<=30000;i++)
    {                           
        fa[i]=i;
        sum[i]=1;
    }//初始化
    for(int i=1;i<=t;i++)
    {
        char ch;
        int x,y;
        cin>>ch>>x>>y;
        int fx=find(x);                                  
        int fy=find(y);                             
        if(ch=='M')
        {
            dist[fx]+=sum[fy];       
            fa[fx]=fy;                                    
            sum[fy]+=sum[fx];                         
            sum[fx]=0;                   
        }//每次处理
        if(ch=='C')
        {
            if(fx!=fy)
                printf("-1\n");          
            else 
                printf("%d\n",abs(dist[x]-dist[y])-1);
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/fusiwei/p/11318964.html