제출 #1330713

#제출 시각아이디문제언어결과실행 시간메모리
1330713Faisal_Saqib늑대인간 (IOI18_werewolf)C++20
100 / 100
999 ms172928 KiB
#include "werewolf.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N=1e6+100,LG=20;
int tin1[N],tout1[N],par1[N][LG];
int par[N][LG],inv[N],pr[N],tin[N],tout[N],val[N],vals[N],tmp=0;
vector<int> ma[N],sf[N];
int get(int x)
{
  return (pr[x]==x)?x:pr[x]=get(pr[x]);
}
void dfs(int x,int p=0)
{
  par[x][0]=p;
  for(int j=1;j<LG;j++)par[x][j]=par[par[x][j-1]][j-1];
  tin[x]=++tmp;
  for(auto y:sf[x])
  {
    dfs(y,x);
  }
  tout[x]=tmp;
    // cout<<"Suffix tree "<<x<<' '<<tin[x]<<' '<<tout[x]<<endl;

}
void dfs1(int x,int p=0)
{
  par1[x][0]=p;
  for(int j=1;j<LG;j++)par1[x][j]=par1[par1[x][j-1]][j-1];
  tin1[x]=++tmp;
  inv[tmp]=x;
  for(auto y:sf[x])
  {
    dfs1(y,x);
  }
  tout1[x]=tmp;
  // cout<<"Prefix tree "<<x<<' '<<tin1[x]<<' '<<tout1[x]<<endl;
}
int ogn,tt;
vector<int> cur[N<<1];
void build(int l=1,int r=tt,int v=1)
{
  for(int k=l;k<=r;k++)
  {
    int x=inv[k];
    if(1<=x and x<=ogn)
    {
      // cout<<"adding "<<x<<' '<<tin[x]<<" to range "<<l<<' '<<r<<endl;
      cur[v].push_back(tin[x]);
    }
  }
  sort(begin(cur[v]),end(cur[v]));
  if(l==r)
  {
    return;
  }
  int m=(l+r)>>1,lc=v<<1,rc=lc|1;
  build(l,m,lc);
  build(m+1,r,rc);
}
bool count(int ql,int qr,int vl,int vr,int l=1,int r=tt,int v=1)
{
  if(qr<l or r<ql)return 0;
  if(ql<=l and r<=qr)
  {
    auto it=lower_bound(begin(cur[v]),end(cur[v]),vl);
    // cout<<"finding "<<vl<<' '<<vr<<" in "<<ql<<' '<<qr<<endl;
    // cout<<"cur "<<l<<' '<<r<<endl;
    // for(auto x:cur[v])cout<<x<<' ';
    // cout<<endl;
    if(it!=end(cur[v]) and *it <= vr) return 1;
    return 0;
  }
  // check if any element in range [ql,qr] is in the range [vl,vr]
  int m=(l+r)>>1,lc=v<<1,rc=lc|1;
  return count(ql,qr,vl,vr,l,m,lc)|count(ql,qr,vl,vr,m+1,r,rc);
}
std::vector<int> check_validity(int n, std::vector<int> X, std::vector<int> Y,
                                std::vector<int> S, std::vector<int> E,
                                std::vector<int> L, std::vector<int> R) {
  int Q = S.size();
  ogn=n;
  tmp=0;
  for(int i=0;i<=3*n;i++)
    ma[i].clear(),pr[i]=i,sf[i].clear();
  for(int i=0;i<X.size();i++)
  {
    X[i]++;
    Y[i]++;
    ma[X[i]].push_back(Y[i]);
    ma[Y[i]].push_back(X[i]);
    // cout<<X[i]<<' '<<Y[i]<<endl;
  }
  // 
  int nxt=n;
  val[0]=-1e9;
  // constructing the suffix tree
  for(int p=n;p>=1;p--){
    val[p]=-1e9;
    // int ogp=p;
    for(auto y:ma[p])
    {
      if(y>=p)
      {
        y=get(y);
        int op=get(p);
        if(y!=op)
        {
          nxt++;
          // cout<<nxt<<' '<<y<<endl;
          // cout<<nxt<<' '<<op<<endl;
          sf[nxt].push_back(y);
          sf[nxt].push_back(op);
          pr[y]=nxt;
          pr[op]=nxt;
          val[nxt]=p;
        }
      }
    }
  }
  // cout<<"ever ending "<<endl;
  tmp=0;
  dfs(nxt);
  tt=nxt;
  // making the prefix tree
  for(int i=0;i<=3*n;i++)
    pr[i]=i,sf[i].clear(),vals[i]=val[i];
  nxt=n;
  val[0]=1e9;
  for(int p=1;p<=n;p++){
    val[p]=1e9;
    for(auto y:ma[p])
    {
      if(y<=p)
      {
        y=get(y);
        int op=get(p);
        if(y!=op)
        {
          nxt++;
          // cout<<nxt<<' '<<y<<endl;
          // cout<<nxt<<' '<<op<<endl;
          sf[nxt].push_back(y);
          sf[nxt].push_back(op);
          pr[y]=nxt;
          pr[op]=nxt;
          val[nxt]=p;
        }
      }
    }
  }
  // cout<<"prefix"<<endl;
  tmp=0;
  dfs1(nxt);
  build();

  vector<int> A(Q);
  for (int i = 0; i < Q; ++i) {
    int s=S[i]+1,e=E[i]+1,l=L[i]+1,r=R[i]+1;
    // cout<<"query "<<i<<' '<<s<<' '<<e<<' '<<l<<' '<<r<<endl;
    for(int j=LG-1;j>=0;j--)
    {
      if(vals[par[s][j]]>=l)
      {
        s=par[s][j];
      }
      if(val[par1[e][j]]<=r)
      {
        e=par1[e][j];
      }
    }
    // cout<<"Ended up at "<<s<<' '<<e<<endl;
    // cout<<val[s]<<' '<<vals[s]<<endl;
    // cout<<val[e]<<' '<<vals[e]<<endl;
    // cout<<tin1[e]<<' '<<tout1[e]<<endl;
    // cout<<tin[s]<<' '<<tout[s]<<endl;
    A[i]=count(tin1[e],tout1[e],tin[s],tout[s]);
    // A[i]=(mi>=l or mx<=r);
  }
  return A;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...