Submission #1364396

#TimeUsernameProblemLanguageResultExecution timeMemory
1364396ByeWorldWerewolf (IOI18_werewolf)C++20
100 / 100
379 ms87908 KiB
#include "werewolf.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O3", "Ofast")
#define ll long long
#define se second
#define fi first
#define pb push_back
#define lf (id<<1)
#define rg ((id<<1)|1)
#define md ((l+r)>>1)
using namespace std;
typedef pair<int,int> pii;
typedef pair<pii,pii> ipii;
const int MAXN = 6e5+10;
const int MAXA = 5e4+10;
const int SQRT = 300;
const int INF = 2e9;
const int MOD = 1e9+87;
const int MOD2 = 1e9+7;
const int LOG = 30;
void chmn(auto &a, auto b){ a = min(a, b); }
void chmx(auto &a, auto b){ a = max(a, b); }

int n, q, sta[MAXN], en[MAXN], ans[MAXN], l[MAXN], r[MAXN];
array<int,4> que[MAXN];
vector<int> adj[MAXN];

struct dsu {
	int par[MAXN];
	void bd(){
		for(int i=1; i<=MAXN-10; i++) par[i] = i;
	}
	int f(int x){
		return (par[x]==x ? x : par[x] = f(par[x]));
	}
	bool con(int x, int y){
		return f(x) == f(y);
	}
	void mer(int x, int y){
		x = f(x); y = f(y); 
		par[x] = y;
	}
} DSU;

vector<array<int,3>> sol[MAXN];
vector<int> poi[MAXN];

struct seg {
	int st[4*MAXN];
	int que(int id,int l,int r,int x,int y){
		if(x<=l && r<=y) return st[id];
		if(r<x || y<l) return 0;
		return que(lf,l,md,x,y)+que(rg,md+1,r,x,y);
	}
	int upd(int id,int l,int r,int x,int y){
		if(l==r && l==x) return st[id] += y;
		if(r<x || x<l) return st[id];
		return st[id] = upd(lf,l,md,x,y)+upd(rg,md+1,r,x,y);
	}
} A;
void solve(){
	for(int i=1; i<=q; i++){
		// for(int j=0; j<4; j++) cout << que[i][j] << ' ';
		// cout << " xx\n";

		sol[que[i][0]-1].pb({que[i][2], que[i][3], -i});
		sol[que[i][1]].pb({que[i][2], que[i][3], i});
	}
	for(int i=1; i<=n; i++){
		for(auto y : poi[i]) A.upd(1,1,n,y,1);

		for(auto [l,r,id] : sol[i]){
			if(id < 0) ans[-id] -= A.que(1,1,n,l,r);
			else ans[id] += A.que(1,1,n,l,r);
		}
	}
}

vector<int> tree[MAXN];
int vis = 0, val[MAXN], le[MAXN], ri[MAXN];
void dfs(int nw){
	if(tree[nw].size() == 0){ // leaf
		if(val[nw] != 0){
			poi[val[nw]].pb(vis+1);
			// cout << nw << ' '<< val[nw] << ' '<< vis+1 << " point\n";
		}
		val[nw] = ++vis;
	}
	for(auto nx : tree[nw]) dfs(nx);
}

vector<int> vec[MAXN];
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) {
	n = N; q = S.size();
	for(int i=0; i<X.size(); i++){
		adj[X[i]+1].pb(Y[i]+1);
		adj[Y[i]+1].pb(X[i]+1);
	}
	for(int i=1; i<=q; i++){
		sta[i] = S[i-1]+1, en[i] = E[i-1]+1;
		l[i] = L[i-1]+1, r[i] = R[i-1]+1;
		vec[r[i]].pb(i);
		// l[i] <= human, were <= r[i] 
	}
	
	{//were
		DSU.bd();
		int cnt = n;
		for(int i=1; i<=n; i++){
			for(auto nx : adj[i]){
				if(nx > i) continue;
				if(DSU.con(nx, i)) continue;
				++cnt;
				int a = DSU.f(nx), b = DSU.f(i);
				DSU.mer(a, cnt); DSU.mer(b, cnt);
				tree[cnt].pb(a); tree[cnt].pb(b);
			}
		}

		dfs(cnt);
		DSU.bd();
		cnt = n;
		for(int i=1; i<=n; i++) le[i] = ri[i] = val[i];
		for(int i=1; i<=n; i++){
			for(auto nx : adj[i]){
				if(nx > i) continue;
				if(DSU.con(nx, i)) continue;
				++cnt;
				int a = DSU.f(nx), b = DSU.f(i);
				DSU.mer(a, cnt); DSU.mer(b, cnt);
				le[cnt] = min(le[a], le[b]); ri[cnt] = max(ri[a], ri[b]);
				// cout << cnt << ' '<< le[cnt] << ' '<< ri[cnt] << "ab\n";
			}

			for(auto idx : vec[i]){
				int s = DSU.f(en[idx]);
				que[idx][0] = le[s]; que[idx][1] = ri[s];
				// cout << idx <<' '<<en[idx] <<' '<<s<< ' '<< le[s] <<' '<<ri[s] <<" ri\n";
			}
		}
	}
	{//human
		for(int i=1; i<=MAXN-10; i++){
			tree[i].clear(); vec[i].clear();
		}
		for(int i=1; i<=q; i++) vec[l[i]].pb(i);

		DSU.bd();
		int cnt = n;
		for(int i=n; i>=1; i--){
			for(auto nx : adj[i]){
				if(nx < i) continue;
				if(DSU.con(nx, i)) continue;
				++cnt;
				int a = DSU.f(nx), b = DSU.f(i);
				DSU.mer(a, cnt); DSU.mer(b, cnt);
				tree[cnt].pb(a); tree[cnt].pb(b);
			}
		}

		vis = 0; dfs(cnt);
		DSU.bd();
		cnt = n;
		for(int i=1; i<=n; i++) le[i] = ri[i] = val[i];
		for(int i=n; i>=1; i--){
			for(auto nx : adj[i]){
				if(nx < i) continue;
				if(DSU.con(nx, i)) continue;
				++cnt;
				int a = DSU.f(nx), b = DSU.f(i);
				DSU.mer(a, cnt); DSU.mer(b, cnt);
				le[cnt] = min(le[a], le[b]); ri[cnt] = max(ri[a], ri[b]);
				// cout << cnt << ' '<< le[cnt] << ' '<< ri[cnt] << "ab\n";
			}

			for(auto idx : vec[i]){
				int s = DSU.f(sta[idx]);
				que[idx][2] = le[s]; que[idx][3] = ri[s];
				// cout << idx <<' '<<en[idx] <<' '<<s<< ' '<< le[s] <<' '<<ri[s] <<" ri\n";
			}
		}
	}


	solve();
  	vector<int> A;
  	for(int i=1; i<=q; i++) A.pb(ans[i]>=1);
	return A;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...