Cod sursa(job #1766103)

Utilizator mircea_marian.popaPopa Mircea-Marian mircea_marian.popa Data 27 septembrie 2016 14:41:10
Problema Atac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.1 kb
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

struct myList {
    unsigned short info;
    myList *next;
};

struct treeNod {
    unsigned short parent, level, ancestor, section;
    unsigned int numOfBombs, costToAncestor;
    myList *firstChild, *lastChild;
    treeNod(){
        firstChild = lastChild = NULL;
        parent = 32001;
    }
    void addChild(unsigned short chi){
        myList *newCh =  new myList;
        newCh->info = chi;
        newCh->next = NULL;
        if( lastChild != NULL ){
            lastChild->next = newCh;
            lastChild = newCh;
        } else
            firstChild = lastChild = newCh;
    }
    void removeChildren(void){
        myList *ch1 = firstChild, *ch2;
        while(ch1 != NULL){
            ch2 = ch1;
            ch1 = ch1->next;
            delete ch2;
        }
    }
    void printNode(void){
        myList *newCh = firstChild;
        cout << "parent: " << parent << ", level: " << level << ", section: " << section <<
            ", ancestor: " << ancestor << ", numberOfBombs: " << numOfBombs << ", costToAncestor: " << costToAncestor << endl;
        cout << "children :";
        while( newCh ){
            cout << newCh->info << " ";
            newCh = newCh->next;
        }
        cout << endl;
    }
};

unsigned short maxH, N, A, B, C, D;
treeNod *tree;

void dfsFunc( unsigned short nodeIndex , void func(unsigned short) ){
    myList* iterator = tree[nodeIndex].firstChild;
    while( iterator ){
        func(iterator->info);
        dfsFunc(iterator->info,func);
        iterator = iterator->next;
    }
}

void setLevels(unsigned short nodeIndex){
    tree[nodeIndex].level = tree[tree[nodeIndex].parent].level + 1;
    if( !tree[nodeIndex].firstChild && maxH < tree[nodeIndex].level )
        maxH = tree[nodeIndex].level;
}

void setSections(unsigned short nodeIndex){
    if( tree[nodeIndex].level % maxH == 0 ){
            tree[nodeIndex].ancestor = nodeIndex;
            tree[nodeIndex].costToAncestor = 100003;
    } else {
        tree[nodeIndex].ancestor = tree[tree[nodeIndex].parent].ancestor;
        tree[nodeIndex].costToAncestor = (tree[tree[nodeIndex].parent].costToAncestor < tree[nodeIndex].numOfBombs) ?
            tree[tree[nodeIndex].parent].costToAncestor : tree[nodeIndex].numOfBombs;
    }
    tree[nodeIndex].section = tree[nodeIndex].level/maxH;
}

unsigned int getCost(unsigned short X,
        unsigned short Y){
    if( X == Y )
            return 0;
    unsigned int cost = 100001;
    while( tree[X].section != tree[Y].section ){
        if( tree[X].section < tree[Y].section ){

            if( cost > tree[Y].costToAncestor )
                cost  = tree[Y].costToAncestor;

            Y = tree[Y].ancestor;

            if( cost > tree[Y].numOfBombs )
                cost = tree[Y].numOfBombs;

            Y = tree[Y].parent;
        } else {

            if( cost > tree[X].costToAncestor )
                cost = tree[X].costToAncestor;

            X = tree[X].ancestor;

            if( cost > tree[X].numOfBombs )
                cost = tree[X].numOfBombs;

            X = tree[X].parent;
        }
    }
    while( X != Y ){
        if( tree[X].level < tree[Y].level ){
            if( cost > tree[Y].numOfBombs )
                cost = tree[Y].numOfBombs;
            Y = tree[Y].parent;
        } else {
            if( cost > tree[X].numOfBombs )
                cost = tree[X].numOfBombs;
            X = tree[X].parent;
        }
    }
    return cost;
}

void formulaIndexes(unsigned short& X, unsigned short& Y, unsigned int Z){

    X++;
    Y++;

    X = (X * A + Y * B) % N;
    Y = (Y * C + Z * D) % N;
}

int main(){
    fstream fis;
    fis.open("atac.in", ios::in);
    unsigned short i, X, Y, root;
    unsigned int P, M, nB, Z;
    maxH = 0;
    fis >> N >> M >> P;
    tree = new treeNod [N];
    i = 2;
    while( i <= N ){
        fis >> A >> nB;
        i--;
        A--;
        if( tree[A].parent == 32001 ){
            tree[A].parent = i;
            tree[i].addChild(A);
            tree[A].numOfBombs = nB;
        } else {
            tree[i].parent = A;
            tree[A].addChild(i);
            tree[i].numOfBombs = nB;
        }
        i+=2;
    }
    fis >> X >> Y >> A >> B >> C >> D;
    X--;
    Y--;
    fis.close();

    for( i = 0 ; i < N ; i++ )
        if( tree[i].parent == 32001 ){
            tree[i].level = 0;
            maxH = 0;
            dfsFunc( i , setLevels );
            root = i;
            break;
        }

    maxH = (unsigned short)sqrt(maxH);

    tree[root].ancestor = root;
    tree[root].costToAncestor = 100003;

    dfsFunc(root,setSections);

    unsigned int j;
    nB = M - P;
    Z = getCost( X , Y );
    for( j = 2 ; j <= nB ; j++ ){
        formulaIndexes(X , Y , Z);
        Z = getCost(X , Y);
    }

    fis.open("atac.out", ios::out);

    for( j = nB + 1 ; j <= M ; j++ ){
        formulaIndexes(X , Y , Z);
        Z = getCost(X,Y);
        fis << Z <<  endl;
    }

    fis.close();

    /*for( i = 0 ; i <  N ; i++ ){
        cout << i << "\t";
        tree[i].printNode();
    }*/

    for( i = 0 ; i < N ; i++ )
        tree[i].removeChildren();
    delete [] tree;
}