제출 #1328643

#제출 시각아이디문제언어결과실행 시간메모리
1328643animal_migrationTourism (JOI23_tourism)C++17
10 / 100
5093 ms21256 KiB
#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define pii pair<int,int>
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define eb emplace_back
#define rep(x,y,z) for (int x=y;x<z;x++)

int par(int x, vector<int> &dsu){
  if (dsu[x]<0) return x;
  return par(dsu[x],dsu);
}

signed main(){
  cin.tie(nullptr)->ios::sync_with_stdio(0);
  //input
  int n,m,q;
  cin>>n>>m>>q;
  vector<vector<int>> G(n);
  rep(i,1,n){
    int u,v;
    cin>>u>>v;
    u--; v--;
    G[u].pb(v);
    G[v].pb(u);
  }
  vector<int> dd(n), ff(n), lf(n), st(n);
  vector<int> ord(n);
  int tim=0;
  function<void(int,int)> dfs=[&](int u, int f){
    ord[tim]=u;
    st[u]=tim++;
    ff[u]=f;
    int p=lf[ff[u]], q=lf[p];
    if (u!=f&&dd[q]-dd[p]==dd[p]-dd[ff[u]]) lf[u]=q;
    else lf[u]=ff[u];
    for (int v:G[u]){
      if (v==f) continue;
      dd[v]=dd[u]+1;
      dfs(v,u);
    }
  };
  dfs(0,0);
  function<int(int,int)> cal=[&](int u, int v){
    if (dd[u]<dd[v]) swap(u,v);
    int cu=u, cv=v;
    while (dd[u]>dd[v]){
      if (dd[lf[u]]>=dd[v]) u=lf[u];
      else u=ff[u];
    }
    while (u!=v){
      if (lf[u]!=lf[v]) u=lf[u],v=lf[v];
      else u=ff[u],v=ff[v];
    }
    // cout<<cu+1<<' '<<cv+1<<" lca: "<<u+1<<' '<<dd[cu]+dd[cv]-dd[u]*2+1<<'\n';
    return dd[cu]+dd[cv]-dd[u]*2+1;
  };
  vector<int> A(m);
  vector<int> cop(n,0);
  rep(i,0,m) cin>>A[i], A[i]--, cop[A[i]]++;
  rep(i,0,n){
    if (cop[i]==0){
      A.pb(i); m++;
      cop[i]++;
    }
  }
  // cout<<m<<'\n';
  // rep(i,0,m) cout<<A[i]<<' ';
  // cout<<'\n';
  //precompute lca, dfs order
  //build dsu
  int sz=n;
  vector<int> ll(n);
  vector<int> rr(n);
  vector<int> wl(n), wr(n), hl(n), hr(n);
  //rem function
  #define vit vector<int>::iterator
  vector<int> prv(n), nxt(n);
  stack<pair<vit,int>> row;
  function<void(int,bool)> rem=[&](int x, bool o){
    // cout<<x+1<<' '<<sz<<" -> ";
    x=st[x];
    int lp,rp;
    lp=prv[x];
    rp=nxt[x];
    // cout<<"*"<<ord[x]+1<<' '<<ord[lp]+1<<' '<<ord[rp]+1<<'\n';
    // cout<<cal(ord[x],ord[lp])<<' '<<cal(ord[x],ord[rp])<<' '<<cal(ord[lp],ord[rp])<<'\n';
    sz-=(cal(ord[x],ord[lp])+cal(ord[x],ord[rp])-cal(ord[lp],ord[rp]))/2;
    if (o) row.push({nxt.begin()+prv[x],nxt[prv[x]]});
    if (o) row.push({prv.begin()+nxt[x],prv[nxt[x]]});
    nxt[prv[x]]=rp;
    prv[nxt[x]]=lp;
    // cout<<sz<<'\n';
  };
  //input qry, process
  int bz=300;
  int bn=(m+bz-1)/bz;
  struct Q { int l; int r; int id; };
  auto com=[](Q a, Q b){
    return a.r>b.r;
  };
  vector<vector<Q>> qry(bn);
  rep(i,0,q){
    int l,r;
    cin>>l>>r;
    l--; r--;
    qry[l/bz].pb({l,r,i});
  }
  rep(i,0,bn){
    sort(all(qry[i]),com);
  }
  //sqrt decom
  vector<int> ans(q);
  rep(i,0,bn){
    rep(j,0,n){
      prv[j]=(j-1+n)%n;
      nxt[j]=(j+1)%n;
    }
    sz=n;
    vector<int> fre(cop);
    int ql=0, qr=m-1;
    while (ql<i*bz){
      fre[A[ql]]--;
      if (fre[A[ql]]==0) rem(A[ql],0);
      ql++;
      // cout<<ql<<' '<<qr<<' '<<sz<<'\n';
    }
    for (auto [l,r,id]:qry[i]){
      // cout<<ql<<' '<<qr<<" -> ";
      while (qr>r){
        fre[A[qr]]--;
        if (fre[A[qr]]==0) rem(A[qr],0);
        qr--;
        // cout<<ql<<' '<<qr<<' '<<sz<<'\n';
      }
      int oz=sz;
      while (ql<l){
        fre[A[ql]]--;
        if (fre[A[ql]]==0) rem(A[ql],1);
        ql++;
        // cout<<ql<<' '<<qr<<' '<<sz<<'\n';
      }
      ans[id]=sz;
      sz=oz;
      // cout<<ql<<' '<<qr<<'\n';
      while (!row.empty()){
        auto [it,v]=row.top();
        row.pop();
        *it=v;
      }
      while (ql>i*bz){
        ql--;
        fre[A[ql]]++;
      }
      // cout<<ql<<' '<<qr<<' '<<sz<<'\n';
    }
  }
  //output
  rep(i,0,q){
    cout<<ans[i]<<'\n';
  }
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...