Cod sursa(job #309845)

Utilizator sandyxpSanduleac Dan sandyxp Data 1 mai 2009 12:15:30
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <iostream>
#include <vector>
#include <algorithm>
#define IN "stramosi.in"
#define OUT "stramosi.out"

const int Max_N = 250000+1;
using namespace std;
int A[Max_N][18]; // 2^18 > Max_N
int stramax[Max_N], stra[Max_N];

inline int stram(int p, int i) {
    if (A[p][i] || i == 0 || p == 0)
        return A[p][i];
    return A[p][i] = stram(stram(p, i-1), i-1);
}

#define pi pair<int, int>
vector<pair<pi, int> > Query;
int Output[Max_N];

int main() {
    freopen(IN, "rt", stdin);
    freopen(OUT, "wt", stdout);
    int N, M, i, j, p, q;
    scanf("%d %d", &N, &M);
    for (i = 1; i <= N; ++i) {
        scanf("%d", &A[i][0]);
        stra[i] = i;
    }
    // A[i][j] = al 2^j -lea stramos al lui i
    // Recurenta:
    // A[i][0] = T[i]
    // A[i][j] = A[ A[i][j-1], j-1 ];

    /*
    for (j = 1; (1<<j) < N; ++j)
        for (i = 1; i <= N; ++i)
            A[i][j] = A[ A[i][j-1] ][ j-1 ];
    */

    Query.reserve(N);
    for (j = 0; j < M; ++j) {
        scanf("%d %d", &p, &q);
        Query.push_back(make_pair(make_pair(p, q), j));
    }

    sort(Query.begin(), Query.end());

    for (j = 0; j < M; ++j) {
        p = Query[j].first.first;
        q = Query[j].first.second;
        if (q > N) {
            Output[Query[j].second] = 0;
            continue;
        }
        // al q-lea stramos al lui p
        // vom calcula doar stramosul nr. q-stramax[p] al lui stra[p]
        int step, rez = stra[p], nr = q - stramax[p];

        for (step = 1, i = 0; step < nr; step <<= 1, i++);
        for (; step && nr && rez; step >>= 1, i--)
            if (step <= nr)
                rez = stram(rez, i), nr -= step;

        if (q > stramax[p])
            stramax[p] = q, stra[p] = rez;
        Output[Query[j].second] = rez;
        //printf("%d\n", rez);
    }
    for (j = 0; j < M; ++j)
        printf("%d\n", Output[j]);
    return 0;
}
/* 0 1 2 2 4 1 6 0 8 8 10 10 12 */