Cod sursa(job #1234536)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 27 septembrie 2014 15:22:35
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.48 kb
#include <bits/stdc++.h>

#define VI vector<int>
#define VII vector<pair<int,int>>
#define QI queue<int>

#define ms(a,v) memset( a, v, sizeof( a ) )
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define ROF(i,a,b) for(int i = a; i >= b; i--)
#define foreach(v, c) for( typeof( (c).begin() ) v = (c).begin(); v != (c).end(); ++v)

#define pb push_back
#define pp pair<int,int>
#define mp make_pair
#define fi first
#define se second

#define popcount __builtin_popcount
#define gcd __gcd
#define bit(n,i) ( n & ( 1LL << i ) )
#define lsb(x) ( x & ( -x ) )

#define FIN(str) freopen(str,"r",stdin)
#define FOUT(str) freopen(str,"w",stdout)
#define Fin(str) ifstream(str)
#define Fout(str) ostream(str)
#define SYNC ios_base::sync_with_stdio(0);

#define ll long long
#define ull unsigned long long

inline void read( int &a )
{
    register char ch;
    a = 0;
    int sign = 1;

    do
    {
        ch = getchar();

    } while ( !isdigit( ch ) && ch != '-' );

    if ( ch == '-' )
    {
        sign = -1;
        ch = getchar();
    }

    do
    {
        a = a * 10 + ch - '0';
        ch = getchar();

    } while( isdigit( ch ) );

    a *= sign;
}

inline void write( int a )
{
    char s[20];
    int i = 0;
    int sign = 1;

    if ( a < 0 )
        sign = -1,
        a = -a;

    do
    {
        s[ i++ ] = a % 10 + '0';
        a /= 10;

    } while ( a );

    i--;

    if ( sign == -1 )
        putchar( '-' );

    while ( i >= 0 ) putchar( s[ i-- ] );
}

const int dx[] = { -1, 0, 1, 0 };
const int dy[] = { 0, 1, 0, -1 };

const int dl[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dc[] = { -1, 0, 1, -1, 1, -1, 0, 1 };

const int INF = 2e9;
const double EPS = 1e-9;

const int Nmax = 1e5 + 2;

const int LgMax = log2(Nmax) + 1;

using namespace std;

int Left[Nmax], Right[Nmax], Parent[Nmax];

bool isRoot( int p )
{
    return ( !Parent[p] || ( Left[ Parent[p] ] != p && Right[ Parent[p] ] != p ) );
}

 void connect(int ch, int p, bool leftChild) {
		if (leftChild)
			Left[p] = ch;
		else
			Right[p] = ch;
		if (ch != 0)
			Parent[ch] = p;
	}

	 void rotate(int x) {
		int p = Parent[x];
		int g = Parent[p];
		bool isRootP = isRoot(p);
		bool leftChildX = (x == Left[p]);

		connect(leftChildX ? Right[x] : Left[x], p, leftChildX);
		connect(p, x, !leftChildX);

		if (!isRootP)
			connect(x, g, p == Left[g]);
		else
			Parent[x] = g;
	}

	 void splay(int x) {
		while (!isRoot(x)) {
			int p = Parent[x];
			int g = Parent[p];
			if (isRoot(p)) {
				// zig
				rotate(x);
			} else if ((x == Left[p]) == (p == Left[g])) {
				// zig-zig
				rotate(p);
				rotate(x);
			} else {
				// zig-zag
				rotate(x);
				rotate(x);
			}
		}
	}

int expose( int p )
{
    int last = 0;

    for ( int x = p; x != 0; x = Parent[x] )
    {
        splay( x );
        Left[x] = last;
        last = x;
    }

    splay( p );

    return last;
}

int findRoot( int p )
{
    expose( p );

    while ( Right[p] != 0 ) p = Right[p];

    return p;
}

void link( int x, int y )
{
    expose( x );
    Parent[x] = y;
}

void cut( int x, int y )
{
    expose( x );
    Parent[ Right[x] ] = 0;
    Right[x] = 0;
}

int N, M;

int main()
{
    FIN("disjoint.in");
    FOUT("disjoint.out");

    read( N ); read( M );

    for ( int i = 1, tip, x, y; i <= M; ++i )
    {
        read( tip ); read( x ); read( y );

        if ( tip == 1 )
            link( x, y );
        else
        {
            if ( findRoot( x ) == findRoot( y ) )
                cout << "DA\n";
            else
                cout << "NU\n";
        }
    }

    return 0;
}