Submission #1276748

#TimeUsernameProblemLanguageResultExecution timeMemory
1276748uzukishinobuWerewolf (IOI18_werewolf)C++20
0 / 100
771 ms172928 KiB
#include "werewolf.h"
#include <bits/stdc++.h>
using namespace std;
int a,b;
vector<pair<int,int>> edge;
vector<vector<vector<int>>> z;
bool cmp(pair<int,int> a,pair<int,int> b){
     return max(a.first,a.second)<max(b.first,b.second);
}
bool cmp1(pair<int,int> a,pair<int,int> b){
     return min(a.first,a.second)>min(b.first,b.second);
}
vector<array<int,2>> val; 
const int LOG = 20;
vector<vector<array<int,2>>> up;
int root1,root2,tour1,tour2;
vector<array<int,2>> rev;
struct dsu{
      vector<int> par;
      vector<int> sz;
      int cur;
      void init(int _a, int sadge){
          cur = _a - 1;
          par.assign(sadge,0);
          for (int i=0;i<sadge;i++){
               par[i]=i;
          }
      }
      int find(int u){
          if (par[u]==u){
              return u;
          }
          return par[u]=find(par[u]);
      }
      void join(int x,int y,int t){
           x=find(x);
           y=find(y);
           if (x==y){
               return;
           }
           cur++;
           val[cur][t]=val[x][t];
           z[cur][t].push_back(x);
           z[cur][t].push_back(y);
           par[y]=cur;
           par[x]=cur;
           up[x][0][t]=cur;
           up[y][0][t]=cur;
      }
};
dsu d;

vector<array<int,2>> sta; 
vector<array<int,2>> fin; 
int tour;

void dfs(int i,int t){
    if (i<0) return;
    tour++;
    sta[i][t]=tour;
    rev[tour][t]=i;
    for (auto p:z[i][t]){
         dfs(p,t);
    }
    fin[i][t]=tour;
}
struct node{
     int l,r,base,id;
};
vector<vector<node>> pos;
vector<int> res;
vector<int> bit;
int BITN;

void update(int i,int valx){
    i++;
    while (i<=BITN){
         bit[i]+=valx;
         i+=i&-i;
    }
}
int query(int i){
    if (i < 0) return 0;
    i++;
    int resq=0;
    while (i>0){
         resq+=bit[i];
         i-=i&-i;
    }
    return resq;
}

vector<int> check_validity(int N, vector<int> X, vector<int> Y,vector<int> S, vector<int> E,vector<int> L, vector<int> R) {
    int q = S.size();
    vector<int> A(q);
    for (int i = 0; i < q; ++i) {
        A[i] = 0;
    }
    a=N;
    b=X.size();
    edge.assign(b, {0,0});
    for (int i=0;i<b;i++){
         edge[i]={X[i],Y[i]};
    }

    int sadge = a + b + 5;
    if (sadge < a+5) sadge = a + 5;

    z.assign(sadge, vector<vector<int>>(2));
    val.assign(sadge, {0,0});
    up.assign(sadge, vector<array<int,2>>(LOG));
    sta.assign(sadge, {0,0});
    fin.assign(sadge, {0,0});
    rev.assign(sadge, {0,0});

    for (int i=0;i<a;i++){
         val[i][0]=val[i][1]=i;
    }
    for (int i=0;i<sadge;i++){
        for (int j=0;j<LOG;j++){
            up[i][j][0]=up[i][j][1]=0;
        }
    }

    sort(edge.begin(),edge.end(),cmp);
    d.init(a, sadge);
    for (int i=0;i<b;i++){
         int u = max(edge[i].first, edge[i].second);
         int v = min(edge[i].first, edge[i].second);
         d.join(u,v,0);
    }
    root1 = d.cur;

    sort(edge.begin(),edge.end(),cmp1);

    d.init(a, sadge);
    for (int i=0;i<b;i++){
         int u = min(edge[i].first, edge[i].second);
         int v = max(edge[i].first, edge[i].second);
         d.join(u,v,1);
    }
    root2 = d.cur;

    if (root1 >= 0) up[root1][0][0] = root1;
    if (root2 >= 0) up[root2][0][1] = root2;

    int maxNodeIndex = max(root1, root2);
    if (maxNodeIndex < a-1) maxNodeIndex = a-1;

    for (int i=0;i<=maxNodeIndex;i++){
        if (up[i][0][0] == 0 && i != root1) up[i][0][0] = i;
        if (up[i][0][1] == 0 && i != root2) up[i][0][1] = i;
    }
    for (int j=1;j<LOG;j++){
         for (int i=0;i<=maxNodeIndex;i++){
              int mid0 = up[i][j-1][0];
              up[i][j][0] = up[mid0][j-1][0];
              int mid1 = up[i][j-1][1];
              up[i][j][1] = up[mid1][j-1][1];
         }
    }

    tour = 0;
    dfs(root1,0);
    tour1 = tour;
    tour = 0;
    dfs(root2,1);
    tour2 = tour;

    pos.assign(tour2 + 2, vector<node>());

    res.assign(q, 0);

    for (int i=0;i<q;i++){
         int x=S[i];
         int y=E[i];
         int l=L[i];
         int r=R[i];

         for (int j=LOG-1;j>=0;j--){
              int nx = up[x][j][1];
              if (nx >= 0 && val[nx][1] >= l){
                  x = nx;
              }
         }
         for (int j=LOG-1;j>=0;j--){
              int ny = up[y][j][0];
              if (ny >= 0 && val[ny][0] <= r){
                  y = ny;
              }
         }
         int idx_add = sta[x][1] - 1;
         int idx_rem = fin[x][1];
         int Lpos = sta[y][0];
         int Rpos = fin[y][0];
         if (idx_add >= 0 && idx_add <= tour2) pos[idx_add].push_back({Lpos,Rpos,-1,i});
         if (idx_rem >= 0 && idx_rem <= tour2) pos[idx_rem].push_back({Lpos,Rpos,1,i});
    }

    BITN = max(1, tour1 + 2);
    bit.assign(BITN+5, 0);

    for (int i=0;i<=tour2;i++){
         if (i){
             int node = rev[i][1];
             if (node >= 0 && node < (int)sta.size()){
                 int pos0 = sta[node][0];
                 if (pos0 > 0 && pos0 <= tour1) update(pos0-1, 1); 
                 else if (pos0 >= 0 && pos0 <= tour1) update(pos0, 1);
             }
         }
         for (auto &p:pos[i]){
              int cnt = query(p.r) - query(p.l-1);
              res[p.id]+= p.base * cnt;
         }
    }

    for (int i=0;i<q;i++){
         A[i]=(res[i]>0);
    }
    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...