답안 #428027

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
428027 2021-06-15T07:24:42 Z 조영욱(#7659) Counterspells (CPSPC17_counterspells) C++17
0 / 100
908 ms 31948 KB
#include <bits/stdc++.h>
using namespace std;

int par[200001][18];
int n;
int ind[200001];
int sz[200001];
int dep[200001];
vector<int> son[200001];
int f=0;
const int INF=1e9;
int tp[200001];

void dfs(int v,int prev) {
    sz[v]=1;
    par[v][0]=prev;
    for(int i=0;i<son[v].size();i++) {
        int nt=son[v][i];
        dep[nt]=dep[v]+1;
        dfs(nt,v);
        sz[v]+=sz[nt];
        if (sz[nt]>sz[son[v][0]]) {
            swap(son[v][0],son[v][i]);
        }
    }
}

void dfs_hld(int v) {
    ind[v]=f++;
    for(int i=0;i<son[v].size();i++) {
        int nt=son[v][i];
        tp[nt]=(i==0?tp[v]:nt);
        dfs_hld(nt);
    }
}

const int siz=262144;
int seg[siz*2];

int sum(int l,int r,int node=1,int nodel=0,int noder=siz-1) {
    if (r<nodel||l>noder) {
        return 1e9;
    }
    if (l<=nodel&&noder<=r) {
        return seg[node];
    }
    int mid=(nodel+noder)/2;
    return min(sum(l,r,node*2,nodel,mid),sum(l,r,node*2+1,mid+1,noder));
}

void update(int i,int val) {
    i+=siz;
    seg[i]=val;
    while (i>1) {
        i/=2;
        seg[i]=min(seg[i*2],seg[i*2+1]);
    }
}

int seg1[siz*2];
int lazy[siz*2];

void propagate(int node,int nodel,int noder) {
    if (lazy[node]!=-1) {
        seg1[node]=lazy[node]*(noder-nodel+1);
        if (node<siz) {
            lazy[node*2]=lazy[node];
            lazy[node*2+1]=lazy[node];
        }
        lazy[node]=-1;
    }
}

int sum1(int l,int r,int node=1,int nodel=0,int noder=siz-1) {
    propagate(node,nodel,noder);
    if (r<nodel||l>noder) {
        return 0;
    }
    if (l<=nodel&&noder<=r) {
        return seg1[node];
    }
    int mid=(nodel+noder)/2;
    return sum1(l,r,node*2,nodel,mid)+sum1(l,r,node*2+1,mid+1,noder);
}

void update1(int l,int r,int val,int node=1,int nodel=0,int noder=siz-1) {
    propagate(node,nodel,noder);
    if (r<nodel||l>noder) {
        return;
    }
    if (l<=nodel&&noder<=r) {
        lazy[node]=val;
        propagate(node,nodel,noder);
        return;
    }
    int mid=(nodel+noder)/2;
    update1(l,r,val,node*2,nodel,mid);
    update1(l,r,val,node*2+1,mid+1,noder);
    seg1[node]=seg1[node*2]+seg1[node*2+1];
}

int query(int u,int v) {
    bool flag=(u==0&&v==4);
    int ret=0;
    while (tp[v]!=tp[u]) {
        ret+=sum1(ind[tp[v]],ind[v]);
        if (flag){
            //printf("%d %d %d\n",ind[tp[v]],ind[v],sum1(ind[tp[v]],ind[v]));
        }
        v=par[tp[v]][0];
    }
    ret+=sum1(ind[u],ind[v]);
    return ret;
}

void upd(int u,int v,int val) {
    while (tp[v]!=tp[u]) {
        update1(ind[tp[v]],ind[v],val);
        v=par[tp[v]][0];
    }
    update1(ind[u],ind[v],val);
}

int arr[200001];

int main(void) {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        int p;
        scanf("%d",&p);
        arr[i]=p;
        son[p].push_back(i);
    }
    memset(par,-1,sizeof(par));
    dfs(0,-1);
    dfs_hld(0);
    for(int j=1;j<18;j++) {
        for(int i=0;i<=n;i++) {
            if (par[i][j-1]!=-1) {
                par[i][j]=par[par[i][j-1]][j-1];
            }
        }
    }
    memset(lazy,-1,sizeof(lazy));
    for(int i=1;i<=n;i++) {
        update(i,INF);
    }
    for(int i=1;i<=n;i++) {
        int now=i;
        update(ind[arr[i]],INF);
        for(int j=17;j>=0;j--){
            int nt=par[now][j];
            if (nt!=-1&&sum(ind[nt],ind[nt]+sz[nt]-1)>dep[i]) {
                now=nt;
            }
        }
        //printf("%d ",dep[i]-dep[now]);
        if (dep[i]%2==0) {
            printf("%d\n",query(now,i));
        }
        else {
            printf("%d\n",dep[i]-dep[now]-query(now,i));
        }
        update(ind[i],dep[i]);
        if (dep[i]%2==0) {
            upd(now,i,0);
        }
        else {
            upd(now,i,1);
        }
    }
}

Compilation message

Main.cpp: In function 'void dfs(int, int)':
Main.cpp:17:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   17 |     for(int i=0;i<son[v].size();i++) {
      |                 ~^~~~~~~~~~~~~~
Main.cpp: In function 'void dfs_hld(int)':
Main.cpp:30:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   30 |     for(int i=0;i<son[v].size();i++) {
      |                 ~^~~~~~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:127:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  127 |     scanf("%d",&n);
      |     ~~~~~^~~~~~~~~
Main.cpp:130:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  130 |         scanf("%d",&p);
      |         ~~~~~^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 17 ms 21196 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 17 ms 21196 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 17 ms 21196 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 908 ms 31948 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 17 ms 21196 KB Output isn't correct
2 Halted 0 ms 0 KB -