Cod sursa(job #1566400)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 12 ianuarie 2016 00:52:17
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.26 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <bitset>

const int NMAX = 120010;
const int SMAX = 1000010;
const int KMAX = 370;
using namespace std;

int NrNodes, NrQuerys, Length, type, st, dr, cost, ok, part, Lazy[NMAX];
int WhatPart[NMAX], Right[NMAX], Left[NMAX], MyVector[NMAX];
int Worker[NMAX], Marked[NMAX], node1, node2, NrParts;
int Start[NMAX], Finish[NMAX], First[NMAX], Last[NMAX];
vector <int> Edges[NMAX]; bitset <SMAX> Sum[KMAX];

void DFS( int node ) {
    NrNodes ++;
    First[node] = NrNodes;
    Last[node]  = NrNodes;
    Worker[NrNodes] = node;
    Marked[node] = 1;

    vector <int> :: iterator it;
    for( it = Edges[node].begin(); it != Edges[node].end(); it ++ ) {
        int nextNode = *it;

        if( !Marked[nextNode] ) {
            DFS( nextNode );
            Last[node] = NrNodes;
        }
    }

    return;
}

int main () {

    freopen( "arbore.in" , "r", stdin  );
    freopen( "arbore.out", "w", stdout );

    scanf( "%d %d", &NrNodes, &NrQuerys );
    for( int i = 1; i < NrNodes; i ++ ) {
        scanf( "%d %d", &node1, &node2 );

        Edges[node1].push_back(node2);
        Edges[node2].push_back(node1);
    }

    NrNodes = 0; DFS( 1 ); Length = sqrt( NrNodes );

    for( int i = 1; i <= NrNodes; i += Length ) {
        NrParts ++;
        Start[NrParts] = i;
        Finish[NrParts] = min( i + Length - 1, NrNodes );
        Sum[NrParts][0] = 1;

        for( int j = i; j < i + Length; j ++ )
            WhatPart[j] = NrParts;
    }

    for( int k = 1; k <= NrQuerys; k ++ ) {
        scanf( "%d", &type );

        switch( type ) {
            case 1: {
                scanf( "%d %d", &st, &cost );
                dr = Last[st]; st = First[st];

                if( WhatPart[st] == WhatPart[dr] ) {

                    for( int i = Start[WhatPart[st]]; i <= Finish[WhatPart[st]]; i ++ )
                        Sum[WhatPart[st]][MyVector[i]] = 0;
                    for( int i = st; i <= dr; i ++ )
                        MyVector[i] += cost;
                    for( int i = Start[WhatPart[st]]; i <= Finish[WhatPart[st]]; i ++ )
                        if( MyVector[i] < SMAX )
                            Sum[WhatPart[st]][MyVector[i]] = 1;

                } else {

                    for( int i = Start[WhatPart[st]]; i <= Finish[WhatPart[st]]; i ++ )
                        Sum[WhatPart[st]][MyVector[i]] = 0;
                    for( int i = st; i <= Finish[WhatPart[st]]; i ++ )
                        MyVector[i] += cost;
                    for( int i = Start[WhatPart[st]]; i <= Finish[WhatPart[st]]; i ++ )
                        if( MyVector[i] < SMAX )
                            Sum[WhatPart[st]][MyVector[i]] = 1;

                    for( int i = Finish[WhatPart[st]] + 1; WhatPart[i] != WhatPart[dr]; i += Length )
                        Lazy[WhatPart[i]] += cost;

                    for( int i = Start[WhatPart[dr]]; i <= Finish[WhatPart[dr]]; i ++ )
                        Sum[WhatPart[dr]][MyVector[i]] = 0;
                    for( int i = Start[WhatPart[dr]]; i <= dr; i ++ )
                        MyVector[i] += cost;
                    for( int i = Start[WhatPart[dr]]; i <= Finish[WhatPart[dr]]; i ++ )
                        if( MyVector[i] < SMAX )
                            Sum[WhatPart[dr]][MyVector[i]] = 1;
                }

                break;
            }
            case 2: {
                scanf( "%d", &cost ); ok = 0; part = 0;

                for( int i = 1; i <= NrParts; i ++ ) {
                    if( cost - Lazy[i] >= 0 )
                    if( Sum[i][cost - Lazy[i]] == 1 ) {
                        ok = 1; part = i;
                        break;
                    }
                }

                if( ok == 0 )
                    printf( "-1\n" );
                else {
                    for( int i = Start[part]; i <= Finish[part]; i ++ ) {
                        if( MyVector[i] == cost - Lazy[part] ) {
                            printf( "%d\n", Worker[i] );
                            break;
                        }
                    }
                }

                break;
            }
        }

    }

    return 0;
}