Submission #778809

#TimeUsernameProblemLanguageResultExecution timeMemory
778809Ahmed57Cats or Dogs (JOI18_catdog)C++17
100 / 100
364 ms26828 KiB
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")

#include <bits/stdc++.h>
#include "catdog.h"
using namespace std;
vector<int> adj[200001];
int n;
int val[200001];
int sz[200001];
int P[200001];
int arr[200001];
int root[200001];
int down[200001];
void co(int i,int pr){
    sz[i] = 1;
    for(auto j:adj[i]){
        if(j==pr)continue;
        co(j,i);
        sz[i]+=sz[j];
    }
}
int no = 1;
void dfs(int i,int pr,int ro){
    val[i] = no++;
    root[i] = ro;
    down[ro] = i;
    P[i] = pr;
    int ma = -1 , su = 0;
    for(auto j:adj[i]){
        if(j==pr)continue;
        if(ma<sz[j]){
            ma = sz[j];
            su = j;
        }
    }
    if(ma!=-1)dfs(su,i,ro);
    for(auto j:adj[i]){
        if(j==pr||j==su)continue;
        dfs(j,i,j);
    }
}
struct node{
  int dp[2][2];
  node(){
    for(int i = 0;i<2;i++){
      for(int j = 0;j<2;j++){
        dp[i][j] = 1e5;
      }
    }
  }
}seg[400001];
node combine(node a,node b){
    node ans;
    for(int i = 0;i<2;i++){
      for(int j = 0;j<2;j++){
        for(int k = 0;k<2;k++){
          for(int l = 0;l<2;l++){
            ans.dp[i][j] = min(ans.dp[i][j],a.dp[i][k]+b.dp[l][j]+(k != l));
          }
        }
      }
    }
    return ans;
}
void build(int l,int r,int p){
    //cout<<l<<" "<<r<<" "<<p<<endl;
    if(l==r){
        seg[p].dp[0][0] = 0;
        seg[p].dp[1][1] = 0;
        seg[p].dp[0][1] = 1e5;
        seg[p].dp[1][0] = 1e5;
        return ;
    }
    int md = (l+r)/2;
    build(l,md,p*2);
    build(md+1,r,p*2+1);
    seg[p] = combine(seg[p*2],seg[p*2+1]);
}
void update(int l,int r,int p,int idx,pair<int,int> val){
    if(l==r){
        seg[p].dp[0][0] = val.first;
        seg[p].dp[1][1] = val.second;
        seg[p].dp[0][1] = 1e5;
        seg[p].dp[1][0] = 1e5;
        return ;
    }
    int md = (l+r)/2;
    if(idx<=md)update(l,md,p*2,idx,val);
    else update(md+1,r,p*2+1,idx,val);
    seg[p] = combine(seg[p*2],seg[p*2+1]);
}
node query(int l,int r,int p,int lq,int rq){
    //cout<<p<<" "<<l<<" "<<r<<endl;
    if(l>=lq&&r<=rq)return seg[p];
    int md = (l+r)/2;
    if(lq<=md&&rq>=md+1){
        return combine(query(l,md,p*2,lq,rq),query(md+1,r,p*2+1,lq,rq));
    }
    if(lq<=md){
        return query(l,md,p*2,lq,rq);
    }else return query(md+1,r,p*2+1,lq,rq);
}
int coll[100001];
int sum[100001][2];
int prv[100001][2];
node upd(int x){
    if(coll[x]==0)update(1, n,1, val[x], {sum[x][0], 1e5});
    if(coll[x]==1)update(1, n,1, val[x], {1e5, sum[x][1]});
    if(coll[x]==2)update(1, n,1, val[x], {sum[x][0], sum[x][1]});
    x = root[x];
    //cout<<x<<" "<<val[x]<<" "<<val[down[x]]<<"rng"<<endl;
    node ans = query(1,n,1,val[x],val[down[x]]);
    if(x==1){
        return ans;
    }
    for(int i = 0;i<2;i++){
        sum[P[x]][i] -= prv[x][i];
        int best = 1e5;
        for(int j = 0;j<2;j++){
            best = min(best,ans.dp[i][j]);
            best = min(best,ans.dp[i ^ 1][j] + 1);
        }
        prv[x][i] = best;
        sum[P[x]][i]+=prv[x][i];
    }
    return upd(P[x]);
}
void initialize(int N,vector<int>A,vector<int>B){
    n = N;
    coll[0] = 2;coll[N] = 2;
    for(int i = 0;i<N-1;i++){
        coll[i+1] = 2;
        adj[A[i]].push_back(B[i]);
        adj[B[i]].push_back(A[i]);
    }
    //cout<<"ff"<<endl;
    co(1,1);
    //cout<<"ff"<<endl;
    dfs(1,1,1);
    //cout<<"ff"<<endl;
    build(1,n,1);
    //cout<<"ff"<<endl;
}
int cat(int v){
    coll[v] = 0;
    //cout<<"ff"<<endl;
    node ans = upd(v);
    int best = 1e5;
    for(int i = 0;i<2;i++){
        for(int j = 0;j<2;j++){
            best = min(best,ans.dp[i][j]);
        }
    }
    return best;
}int dog(int v){
    coll[v] = 1;
    node ans = upd(v);
    int best = 1e5;
    for(int i = 0;i<2;i++){
        for(int j = 0;j<2;j++){
            best = min(best,ans.dp[i][j]);
        }
    }
    return best;
}int neighbor(int v){
    coll[v] = 2;
    node ans = upd(v);
    int best = 1e5;
    for(int i = 0;i<2;i++){
        for(int j = 0;j<2;j++){
            best = min(best,ans.dp[i][j]);
        }
    }
    return best;
}/*
int main(){
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int N = 5;
    vector<int> A = {1,2,2,4};
    vector<int> B = {2,3,4,5};
    initialize(N,A,B);
    cout<<"hh"<<endl;
    cout<<cat(3)<<"jjjjjjjjjjjj"<<endl;
    cout<<dog(5)<<"jjjjjjjjjjjj"<<endl;
    cout<<dog(1)<<"jjjjjjjjjjjj"<<endl;
    cout<<cat(2)<<"jjjjjjjjjjjj"<<endl;
    cout<<neighbor(2)<<"jjjjjjjjjjjj"<<endl;
}*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...