Cod sursa(job #2329916)

Utilizator PredaBossPreda Andrei PredaBoss Data 27 ianuarie 2019 17:46:03
Problema Atac Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("atac.in");
ofstream fout("atac.out");
vector<int>nod[32005],line,val;
int n,m,p,x,y,a,b,c,d,z,cop_n;
int ap[32005],dp[32005];
int lca[20][32005],last[20][32005],cost[20][32005];
void go_visit(int pos,int length)
{
    ap[pos]=line.size();
    dp[pos]=length;
    line.push_back(pos);
    val.push_back(length);
    for(int i=0;i<nod[pos].size();i++)
    {
        go_visit(nod[pos][i],length+1);
        line.push_back(pos);
        val.push_back(length);
    }
}
void rmq_lca()
{
    for(int i=0;i<n;i++)
        lca[0][i]=i;
    for(int i=1;(1<<i)<=n;i++)
        for(int j=0;j<=n-(1<<i);j++)
            if(val[lca[i-1][j]]<val[lca[i-1][j+(1<<(i-1))]])
                lca[i][j]=lca[i-1][j];
            else
                lca[i][j]=lca[i-1][j+(1<<(i-1))];
}
int find_mn(int child,int parent)
{
    int dif=dp[child]-dp[parent];
    int rez=INT_MAX;
    for(int i=0;i<=16 && (1<<i)<=dif;i++)
        if(((1<<i)&dif)!=0)
        {
            rez=min(rez,cost[i][child]);
            child=last[i][child];
        }
    return rez;
}
void change()
{
    x=(x*a+y*b)%cop_n+1;
    y=(y*c+d*z)%cop_n+1;
}
int main()
{
    fin>>n>>m>>p;
    cop_n=n;
    for(int i=2;i<=n;i++)
    {
        fin>>x>>y;
        nod[x].push_back(i);
        cost[0][i]=y;
        last[0][i]=x;
    }
    fin>>x>>y>>a>>b>>c>>d;
    go_visit(1,1);
    n=line.size();
    rmq_lca();
    for(int i=1;i<=16;i++)
        for(int j=1;j<=cop_n;j++)
        {
            last[i][j]=last[i-1][last[i-1][j]];
            cost[i][j]=min(cost[i-1][j],cost[i-1][last[i-1][j]]);
        }
    for(int i=1;i<=m;i++)
    {
        if(x==y)
        {
            z=0;
            change();
            if(i>=m-p+1)
                fout<<z<<"\n";
            continue;
        }
        int cop_x=x;
        int cop_y=y;
        x=ap[x];
        y=ap[y];
        if(x>y)swap(x,y);
        int j=0;
        while((1<<(j+1))<=y-x+1)j++;
        int p2=y-(1<<j)+1;
        int parent;
        if(val[lca[j][x]]<val[lca[j][p2]])
            parent=line[lca[j][x]];
        else
            parent=line[lca[j][x]];
        z=min(find_mn(cop_x,parent),find_mn(cop_y,parent));
        x=cop_x;
        y=cop_y;
        change();
        if(i>=m-p+1)
            fout<<z<<"\n";
    }
    return 0;
}