Cod sursa(job #790014)

Utilizator andrei.sfrentSfrent Andrei andrei.sfrent Data 20 septembrie 2012 00:39:07
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.24 kb
#include <cstdio>

int N, M;
int *S;
int p2[21];

int log2(int x)
{
    int c = 0;
    while(x)
    {
        c++;
        x = x >> 1;
    }
    return c - 1;
}

void read()
{
    scanf("%d%d\n", &N, &M);
    S = new int[N + 1];
    S[0] = 0;
    for(int i = 1; i <= N; i++)
        scanf("%d", S + i);
}

#define NECALCULAT -1
#define MAXN 250002
int mem[MAXN][33];

int f(int x, int i)
{
    if(i == 0)
        return S[x];
    if(mem[x][i] != NECALCULAT)
        return mem[x][i];
    mem[x][i] = f(f(x, i - 1), i - 1);
    return mem[x][i];
}

void pre()
{
    p2[0] = 1;
    for(int i = 1; i < 21; i++)
        p2[i] = p2[i - 1] * 2;

    for(int i = 0; i <= N; i++)
        for(int j = 0; j < log2(M) + 1; j++)
            mem[i][j] = NECALCULAT;
    for(int i = 0; i <= N; i++)
        for(int j = 0; j < log2(M) + 1; j++)
            mem[i][j] = f(i, j);
}

int solve(int p, int q)
{
    int u = p & (p - 1);
    if(u == 0) // putere a lui 2
        return mem[q][log2(p)];
    return solve(u, mem[q][log2(p - u)]);
}

int main()
{
    freopen("stramosi.in", "r", stdin);
    freopen("stramosi.out", "w", stdout);
    read();
    pre();
    int p, q;
    while(M--)
    {
        scanf("%d%d", &q, &p);
        printf("%d\n", solve(p, q));
    }
    return 0;
}