답안 #209550

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
209550 2020-03-14T14:28:24 Z nicolaalexandra Min-max tree (BOI18_minmaxtree) C++14
0 / 100
293 ms 32552 KB
#include <bits/stdc++.h>
#define DIM 70010
using namespace std;
int whatChain[DIM],positionInChain[DIM],chainFatherNode[DIM],level[DIM],Size[DIM],fth[DIM];
int E[DIM*3],p[DIM*3],first[DIM];
pair <int,int> rmq[30][DIM];
vector <int> chains[DIM],L[DIM];
int nr_chains;
struct segment_tree{
    int maxi,mini,lazy;
};
vector <segment_tree> aint[DIM];

struct _update{
    int x,y,val,dist;
};
_update v[DIM];

int n,m,i,j,x,y,val,dist,lca,k;
char ch;

void dfs (int nod, int tata){
    E[++k] = nod;
    first[nod] = k;
    Size[nod] = 1;
    level[nod] = 1 + level[tata];
    fth[nod] = tata;
    int ok = 0;
    for (auto vecin : L[nod]){
        if (vecin != tata){
            ok = 1;
            dfs (vecin,nod);
            Size[nod] += Size[vecin];
            E[++k] = nod;
        }}

    if (!ok){
        nr_chains++;
        chains[nr_chains].push_back(0);
        chains[nr_chains].push_back(nod);
        whatChain[nod] = nr_chains;
        positionInChain[nod] = 1;
    } else {
        int maxi = 0, poz = 0;
        for (auto vecin : L[nod]){
            if (vecin == tata)
                continue;
            if (Size[vecin] > maxi)
                maxi = Size[vecin], poz = vecin;
        }

        chains[whatChain[poz]].push_back(nod);
        whatChain[nod] = whatChain[poz];
        positionInChain[nod] = chains[whatChain[nod]].size()-1;

        for (auto vecin : L[nod]){
            if (vecin == tata || vecin == poz)
                continue;
            chainFatherNode[whatChain[vecin]] = nod;
        }}}

int get_lca (int x, int y){
    int posx = first[x], posy = first[y];
    if (posx > posy)
        swap (posx,posy);
    int nr = p[posy-posx+1];
    pair <int,int> sol = min (rmq[nr][posx],rmq[nr][posy-(1<<nr)+1]);
    return E[sol.second];
}
void update_lazy (int chain, int nod, int st, int dr){
    if (!aint[chain][nod].lazy)
        return;
    if (st != dr){
        int fiu_st = nod<<1, fiu_dr = (nod<<1)|1;
        aint[chain][fiu_st].mini = aint[chain][fiu_st].maxi = aint[chain][nod].lazy;
        aint[chain][fiu_dr].mini = aint[chain][fiu_dr].maxi = aint[chain][nod].lazy;

        aint[chain][fiu_st].lazy = aint[chain][fiu_dr].lazy = aint[chain][nod].lazy;
    }
    aint[chain][nod].lazy = 0;
}
void update_nod (int chain, int nod, int st, int dr){
    int fiu_st = nod<<1, fiu_dr = (nod<<1)|1;
    aint[chain][nod].maxi = max (aint[chain][fiu_st].maxi,aint[chain][fiu_dr].maxi);
    aint[chain][nod].mini = min (aint[chain][fiu_st].mini,aint[chain][fiu_dr].mini);
}
void update_aint (int chain, int nod, int st, int dr, int x, int y, int val){
    update_lazy (chain,nod,st,dr);
    if (x <= st && dr <= y){
        aint[chain][nod].mini = aint[chain][nod].maxi = val;
        aint[chain][nod].lazy = val;
        update_lazy(chain,nod,st,dr);
        return;
    }
    int mid = (st+dr)>>1;
    if (x <= mid)
        update_aint(chain,nod<<1,st,mid,x,y,val);
    if (y > mid)
        update_aint(chain,(nod<<1)|1,mid+1,dr,x,y,val);

    update_lazy (chain,nod<<1,st,mid);
    update_lazy (chain,(nod<<1)|1,mid+1,dr);

    update_nod (chain,nod,st,dr);
}

int get_val (int chain, int nod, int st, int dr, int poz){
    update_lazy(chain,nod,st,dr);
    if (st == dr)
        return aint[chain][nod].maxi;
    int mid = (st+dr)>>1;
    if (poz <= mid)
        return get_val (chain,nod<<1,st,mid,poz);
    else return get_val(chain,(nod<<1)|1,mid+1,dr,poz);
}

void update_heavy (int x, int y, int val){
    if (whatChain[x] == whatChain[y]){
        int posx = positionInChain[x], posy = positionInChain[y];
        if (posx > posy)
            swap (posx,posy), swap (x,y);

        if (x == lca)
            posx++;
        if (y == lca)
            posy--;

        if (posx <= posy)
            update_aint(whatChain[x],1,1,chains[whatChain[x]].size()-1,posx,posy,val);

        return;
    }
    if (level[chainFatherNode[whatChain[x]]] <= level[chainFatherNode[whatChain[y]]])
        swap (x,y);

    int posx = positionInChain[x], posy = chains[whatChain[x]].size()-1;
    if (chains[whatChain[x]][posx] == lca)
        posx++;
    if (chains[whatChain[x]][posy] == lca)
        posy--;

    if (posx <= posy)
        update_aint(whatChain[x],1,1,chains[whatChain[x]].size()-1,posx,posy,val);

    int nr = chainFatherNode[whatChain[x]];
    update_heavy (nr,y,val);
}
inline int cmp (_update a, _update b){
    return a.dist > b.dist;
}
int main (){

   // ifstream cin ("minmaxtree.in");
   // ofstream cout ("minmaxtree.out");

    cin>>n;
    for (i=1;i<n;i++){
        cin>>x>>y;
        L[x].push_back(y);
        L[y].push_back(x);
    }
    dfs (1,0);

    for (i=1;i<=nr_chains;i++){
        for (j=0;j<chains[i].size()*2;j++)
            aint[i].push_back({0,0,0});
    }

    for (i=1;i<=k;i++)
        rmq[0][i] = make_pair (level[E[i]],i);

    for (i=1;(1<<i)<=k;i++){
        for (j=1;j<=k;j++){
            rmq[i][j] = rmq[i-1][j];
            if (j + (1<<(i-1)) <= k && rmq[i-1][j + (1<<(i-1))].first < rmq[i][j].first)
                rmq[i][j] = rmq[i-1][j + (1<<(i-1))];
        }
    }
    for (i=2;i<=k;i++)
        p[i] = p[i/2] + 1;


    /// am numai maxime

    cin>>m;
    for (i=1;i<=m;i++){
        cin>>ch>>x>>y>>val;
        lca = get_lca (x,y);
        dist = level[x] + level[y] - 2 * level[lca];
        v[i] =  {x,y,val,dist};
    }

    sort (v+1,v+m+1,cmp);

    for (i=1;i<=m;i++){
        int x = v[i].x, y = v[i].y, val = v[i].val;
        lca = get_lca (x,y);
        update_heavy(x,y,val);
    }

    for (i=2;i<=n;i++){
        int val = get_val (whatChain[i],1,1,chains[whatChain[i]].size()-1,positionInChain[i]);
        cout<<i<<" "<<fth[i]<<" "<<val<<"\n";
    }

    return 0;
}

Compilation message

minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:165:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (j=0;j<chains[i].size()*2;j++)
                  ~^~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 5368 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 293 ms 32552 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 197 ms 29436 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 5368 KB Output isn't correct
2 Halted 0 ms 0 KB -