HDU - 5354 2部グラフパーティション+互いに素セット(説明を参照)

5354 - HDU

あなたはポイントを尋ねる場合は、互いに素-設定のチェックを直接使用することは、うまく。

Nポイントは非常に巧妙な感じ、パーティションの最適化ビットと、答えを得るために必要とされます。

#pragma GCC最適化(2)
 の#pragma GCCの最適化(3)
 の#pragma GCCの最適化(4)
の#include <ビット/ STDC ++。H>
 に#define LL長い長
 の#define LD長い二重
 の#defineは、符号なしの長い長いULL
 の#define第Fiが
 #define SE第二
 の#define MK make_pair
 の#define PLL対<LL、LL>
 の#define PLI対<LL、整数>
 の#define PII対<整数、整数>
 の#define SZ(X)((INT)x.size() )
 の#define ALL(X)(X).begin()、(X).END()
 の#define FIOイオス:: sync_with_stdio(偽); cin.tie(0)。使用して

 名前空間はstd; 

CONSTの INT N = 1E5 + 7 const  int型 INF = 0x3f3f3f3f constの LL INF = 0x3f3f3f3f3f3f3f3f const  int型 MOD = 1E9 + 7 constの ダブル EPS = 1E- 8 ;
CONST  ダブル PI = ACOS( - 1 )。

テンプレート < クラス T、クラス S>インラインボイド追加(T&、S b)は{A + B =。もし(> = MOD)A - = MOD;} 
テンプレート < クラスT、クラス S>インラインボイドサブ(T&、S b)は、{ - = B。もし(< 0)、A + = MOD;} 
テンプレート < クラス T、クラス S>インラインBOOL chkmax(T&、S B)は{ 返す <bは?= B、;} 
テンプレート < クラス T、クラス S>インラインブール chkmin(T&、S b)は{ 返す > bは?= B、;} 

MT19937 RNG(。。クロノ:: steady_clock ::今()time_since_epoch())(カウント)。

int型N、M。
ベクター < INT > G [N]。
INTのANS [N]。
INT FA [N]、SZ [N]、XR [N]。
int型のトップ。
PIIのSTK [N]。
INTのTXR [N]。

PII getRoot(INT X){
     場合(FA [X] == x)をリターン MK(0 、X)
    PII RET = getRoot(FA [X])。
    ret.fi ^ = XR [X]。
    リターンRET; 
} 

BOOL団結(INT U、INT V){ 
    PII X = getRoot(U)。
    PIIのY =getRoot(V);
    もし(x.se == y.se){
         リターン(x.fi ^ y.fi)。
    } 
    エルス{
         場合(SZ [x.se < SZ [y.se])スワップ(X、Y)
        FA [y.se] = x.se。
        XR [y.se] =(^ x.fi y.fi ^ 1 )。
        SZ [x.se] + = SZ [y.se]。
        STK [ ++トップ] = MK(x.se、y.se)。
        TXR [トップ] = XR [y.se]。
        アサート(トップ < N)。
        返す ; 
    } 
} 

インライン無効ロールバック(){
     int型 X = STK [トップ] .fi。
    INT Y =のSTK [トップ] .SE。
    XR [Y] = TXR [トップ]。
    トップ - ; 
    SZ [X] - = SZ [Y]。
    FA [Y] = Y。
} 


ボイドのinit(){ 
    トップ = 0 以下のためにint型私= 1 ; iが<= N; iが++ ){ 
        G [i]が.clear(); 
        FA [I] = I。
        SZ [I] = 1 
        XR [I] = 0
    } 
} 

ボイドは(解決int型 L、INT R){
     場合(L == R){ 
        ANS [L] = 1 返します
    } 
    INT preTop = 頂。
    INT半ば= L + R >> 1 BOOLすることができます= ; 

    INT U =ミッド+ 1 ; U <= R; U ++ ){
         ための(自動&V:G [U]){
             場合(V> = L && V <= MID)続けますもし(!{(u、v)と団結)
                することができます = ; 
                U = R + 1 破ります; 
            } 
        } 
    } 

    もし(!{缶)
         のためのINT U = L; U <=ミッド; U ++ ){ 
            ANS [U] = 0 ; 
        } 
    } 
    そうでなければ{ 
        (L、中間)を解きます。
    } 

    一方(上部> preTop)ロールバック(); 

    することができます = ; 

    以下のためのINT U = L。uが=半ばを<; U ++ ){
         ための(自動&V:G [U]){
             場合(V>中間&&のV <= r)は続けますもし(!{V)、(uと団結)
                することができます = ; 
                U = R + 1 破ります; 
            } 
        } 
    } 

    もし(!{缶)
         のためのINT U =ミッド+ 1 ; U <= R; U ++ ){ 
            ANS [U] = 0 ;
        }
    } 
    { 
        (MID解決 + 1 、R)。
    } 

    一方(上部> preTop)ロールバック(); 
} 

int型のmain(){ 

    int型の T。scanf関数(" %のD "、&T)。
    一方、(T-- ){ 
        scanf関数(" %d個の%のD "、&​​N、&M)。
        その中に(); 
        以下のためにint型 I = 1 ; I <= M; iは++ ){
             int型Uを、V。
            scanf関数(" %d個の%d個"、&​​U、& V); 
            G [U] .push_back(V)。
            G [V] .push_back(U)。
        } 
        (解決1 、N)。

        以下のためにint型 i = 1 ; iが<= N; iは++ ){
             場合(ANS [I])のputcharを(' 1 ' )。
            のputchar(' 0 ' ); 
        } 
        プット("" )。
    } 
    戻り 0 
} 

/ * 
* /

 

おすすめ

転載: www.cnblogs.com/CJLHY/p/11224792.html