Submission #532208

#TimeUsernameProblemLanguageResultExecution timeMemory
532208nicholaskWerewolf (IOI18_werewolf)C++14
100 / 100
1409 ms188892 KiB
#include "werewolf.h"
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
using pii=pair <int,int>;
int dsu[400040];
void init(int sz){
    for (int i=0; i<sz; i++) dsu[i]=i;
}
int prt(int node){
    if (dsu[node]==node) return node;
    return dsu[node]=prt(dsu[node]);
}
void unn(int u,int v){
    u=prt(u); v=prt(v);
    if (u==v) return;
    dsu[u]=dsu[v];
}
bool cmp1(pii a,pii b){
    return min(a.x,a.y)>min(b.x,b.y);
}
bool cmp2(pii a,pii b){
    return max(a.x,a.y)<max(b.x,b.y);
}
vector <int> humanGraph[400040],wolfGraph[400040];
int humanP[400040],wolfP[400040]; //leaves permutation
pii humanR[400040],wolfR[400040]; //range
int tme;
int humanval[400040],wolfval[400040];
int humanlca[400040][19],wolflca[400040][19];
pii humanDfs(int cur,int prv){
    humanlca[cur][0]=prv;
    if (humanGraph[cur].empty()){
        humanP[tme]=cur;
        tme++;
        return humanR[cur]={tme-1,tme-1};
    }
    vector <pii> ranges;
    for (auto i:humanGraph[cur]) ranges.pb(humanDfs(i,cur));
    sort(ranges.begin(),ranges.end());
    return humanR[cur]={ranges.front().x,ranges.back().y};
}
pii wolfDfs(int cur,int prv){
    wolflca[cur][0]=prv;
    if (wolfGraph[cur].empty()){
        wolfP[tme]=cur;
        tme++;
        return wolfR[cur]={tme-1,tme-1};
    }
    vector <pii> ranges;
    for (auto i:wolfGraph[cur]) ranges.pb(wolfDfs(i,cur));
    sort(ranges.begin(),ranges.end());
    return wolfR[cur]={ranges.front().x,ranges.back().y};
}
struct wavelet{
	int lo,hi;
	wavelet *lhs=0,*rhs=0;
	vector <int> b;
	wavelet(vector<int>v):wavelet(v.begin(),v.end(),*min_element(v.begin(),v.end()),*max_element(v.begin(),v.end())){};
	~wavelet(){
		if (lhs) delete lhs;
		if (rhs) delete rhs;
	}
	template <typename T> wavelet(T from,T to,int lo_,int hi_){
		lo=lo_;
		hi=hi_;
		if (from>=to||lo==hi) return;
		int mi=lo+(hi-lo)/2;
		auto f=[&](int r){
			return r<=mi;
		};
		b.reserve(to-from+1);
		b.push_back(0);
		for (auto it=from; it!=to; it++) b.push_back(b.back()+f(*it));
		auto mit=stable_partition(from,to,f);
		lhs=new wavelet(from,mit,lo,mi);
		rhs=new wavelet(mit,to,mi+1,hi);
	}
	int lte(int l,int r,int k){
		if (l>r||k<lo) return 0;
		if (hi<=k) return r-l+1;
		return this->lhs->lte(b[l],b[r+1]-1,k)+this->rhs->lte(l-b[l],r-b[r+1],k);
	}
};
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 m=X.size();
    vector <pii> edge;
    for (int i=0; i<m; i++) edge.pb({X[i],Y[i]});
    sort(edge.begin(),edge.end(),cmp1);
    init(2*N);
    int cur=N;
    for (int i=0; i<N; i++) humanval[i]=i;
    for (auto i:edge){
        if (prt(i.x)==prt(i.y)) continue;
        humanGraph[cur].pb(prt(i.x));
        humanGraph[cur].pb(prt(i.y));
        humanval[cur]=min(humanval[prt(i.x)],humanval[prt(i.y)]);
        unn(i.x,cur);
        unn(i.y,cur);
        cur++;
    }
    tme=0;
    for (int i=0; i<2*N; i++){
        for (int j=0; j<19; j++) humanlca[i][j]=-1;
    }
    humanDfs(cur-1,-1);
    for (int j=1; j<19; j++){
        for (int i=0; i<2*N; i++){
            if (humanlca[i][j-1]==-1) humanlca[i][j]=-1;
            else humanlca[i][j]=humanlca[humanlca[i][j-1]][j-1];
        }
    }
    sort(edge.begin(),edge.end(),cmp2);
    init(2*N);
    cur=N;
    for (int i=0; i<N; i++) wolfval[i]=i;
    for (int i=N; i<2*N; i++) wolfval[i]=1e9; 
    for (auto i:edge){
        if (prt(i.x)==prt(i.y)) continue;
        wolfGraph[cur].pb(prt(i.x));
        wolfGraph[cur].pb(prt(i.y));
        wolfval[cur]=max(wolfval[prt(i.x)],wolfval[prt(i.y)]);
        unn(i.x,cur);
        unn(i.y,cur);
        cur++;
    }
    tme=0;
    for (int i=0; i<2*N; i++){
        for (int j=0; j<19; j++) wolflca[i][j]=-1;
    }
    wolfDfs(cur-1,-1);
    for (int j=1; j<19; j++){
        for (int i=0; i<2*N; i++){
            if (wolflca[i][j-1]==-1) wolflca[i][j]=-1;
            else wolflca[i][j]=wolflca[wolflca[i][j-1]][j-1];
        }
    }
    vector <int> poshuman(N);
    for (int i=0; i<N; i++) poshuman[humanP[i]]=i;
    vector <int> r(N);
    for (int i=0; i<N; i++) r[i]=poshuman[wolfP[i]];
    wavelet tree(r);
    vector <int> ans;
    for (int Q=0; Q<S.size(); Q++){
        int st=S[Q],en=E[Q];
        if (humanval[st]<L[Q]||wolfval[en]>R[Q]){
            ans.pb(-1);
            continue;
        }
        for (int i=18; i>=0; i--){
            if (humanlca[st][i]==-1) continue;
            if (humanval[humanlca[st][i]]>=L[Q]) st=humanlca[st][i];
        }
        for (int i=18; i>=0; i--){
            if (wolflca[en][i]==-1) continue;
            if (wolfval[wolflca[en][i]]<=R[Q]) en=wolflca[en][i];
        }
        if (tree.lte(wolfR[en].x,wolfR[en].y,humanR[st].y)!=tree.lte(wolfR[en].x,wolfR[en].y,humanR[st].x-1)) ans.pb(1);
        else ans.pb(0);
    }
    return ans;
}
/*
signed main(){
    int N,M,Q;
    cin>>N>>M>>Q;
    vector <int> X,Y,S,E,L,R;
    for (int i=0; i<M; i++){
        int xj,yj;
        cin>>xj>>yj;
        X.pb(xj);
        Y.pb(yj);
    }
    for (int i=0; i<Q; i++){
        int si,ei,li,ri;
        cin>>si>>ei>>li>>ri;
        S.push_back(si);
        E.push_back(ei);
        L.push_back(li);
        R.push_back(ri);
    }
    vector <int> ans=check_validity(N,X,Y,S,E,L,R);
    for (int i:ans) cout<<i<<' ';
}
*/

Compilation message (stderr)

werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:146:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  146 |     for (int Q=0; Q<S.size(); Q++){
      |                   ~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...