当前位置: 首页 > article >正文

[IOI2018] werewolf 狼人(Kruskal重构树 + 主席树)

https://www.luogu.com.cn/problem/P4899

首先,我们肯定要建两棵Kruskal重构树的,然后判两棵子树是否有相同编号节点

这是个经典问题,我们首先可以拍成dfs序,然后映射过去,然后相当于是判断一个区间是否有 [ l , r ] [l,r] [l,r] 内的数,直接主席树即可。

	#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
 #define debug(...) fprintf(stdout, ##__VA_ARGS__)
 #define debag(...) fprintf(stderr, ##__VA_ARGS__)
#else
 #define debug(...) void(0)
 #define debag(...) void(0)
#endif
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//#define M
//#define mo
#define N 200010
int n, m, i, j, k, T;
int q, u, v; 

vector<int>G1[N], G2[N]; 

struct Node {
	int i, j, k, tot; 
	int F[N], f[N][21], dfn[N], L[N], R[N]; 
	vector<int>G[N]; 
	int fa(int x) { 
		if(F[x] == x) return x; 
		return F[x] = fa(F[x]); 
	}
	void set() {
		for(i = 1; i <= n; ++i) F[i] = i; 
	}
	void add(int x, int y) {
		if(x == fa(y)) return ; 
		debug("cun %d %d\n", x, fa(y)); 
		G[x].pb(fa(y)); F[fa(y)] = x; 
	}
	void dfs(int x) {
		dfn[++tot] = x; L[x] = tot;
		for(int y : G[x]) dfs(y), f[y][0] = x; R[x] = tot; 
	}
	void work() {
		for(k = 1; k <= 20; ++k) 
			for(i = 1; i <= n; ++i) f[i][k] = f[f[i][k - 1]][k - 1];
		debug("dfn "); for(i = 1; i <= n; ++i) debug("%d ", dfn[i]); debug("\n"); 
	}
	pair<int, int> jump(int x, int lim, int op) {
		for(k = 20; k >= 0; --k)
			if(f[x][k]) {
				if(op == 0 && f[x][k] < lim) continue; 
				if(op == 1 && f[x][k] > lim) continue; 
				x = f[x][k]; 
			}
		return {L[x], R[x]}; 
	}
}T1, T2;

int tot, s[N << 5], ls[N << 5], rs[N << 5]; 

struct Segment_tree {
#define mid ((l + r) >> 1)
	void add(int &k, int u, int l, int r, int x) {
		if(!k) k = ++tot; 
		if(l == r) return ++s[k], void(); 
		if(x <= mid) add(ls[k], ls[u], l, mid, x); 
		else add(rs[k], rs[u], mid + 1, r, x); 
		if(!ls[k]) ls[k] = ls[u]; if(!rs[k]) rs[k] = rs[u]; 
		s[k] = s[ls[k]] + s[rs[k]]; 
	}
	int qry(int k, int l, int r, int x, int y) {
		if(l >= x && r <= y) return s[k]; 
		int sum = 0; 
		if(x <= mid) sum += qry(ls[k], l, mid, x, y); 
		if(y >= mid + 1) sum += qry(rs[k], mid + 1, r, x, y); 
		return sum; 
	}
}Seg; 
int rt[N]; 

int a[N], b[N]; 

signed main()
{
	#ifdef LOCAL
	  freopen("in.txt", "r", stdin);
	  freopen("out.txt", "w", stdout);
	#endif
//	srand(time(NULL));
//	T = read();
//	while(T--) {
//
//	}
	n = read(); m = read(); q = read(); 
	for(i = 1; i <= m; ++i) {
		u = read() + 1; v = read() + 1; if(u > v) swap(u, v); 
		debug("%d %d\n", u, v); 
		G1[u].pb(v); G2[v].pb(u); 
	}
	T1.set(); T2.set(); 
	for(i = 1; i <= n; ++i) 
		for(int j : G2[i]) T1.add(i, j); 
	for(i = n; i >= 1; --i) 
		for(int j : G1[i]) T2.add(i, j); 
	T1.dfs(n); T2.dfs(1); T1.work(); T2.work(); 
	for(i = 1; i <= n; ++i) b[T1.dfn[i]] = i; 
	for(i = 1; i <= n; ++i) a[i] = b[T2.dfn[i]]; 
	for(i = 1; i <= n; ++i) debug("%d ", a[i]); debug("\n"); 
	for(i = 1; i <= n; ++i) Seg.add(rt[i], rt[i - 1], 1, n, a[i]); 
	while(q--) {
		int L, R; 
		u = read() + 1; v = read() + 1; L = read() + 1; R = read() + 1; 
		debug("(%d %d) [%d %d]\n", u, v, L, R); 
		if(u < L || v > R) { printf("0\n"); continue; }
		auto t1 = T2.jump(u, L, 0); auto t2 = T1.jump(v, R, 1); 
		int l1 = t1.fi, r1 = t1.se, l2 = t2.fi, r2 = t2.se; 
		debug("[%d %d] [%d %d]\n", l1, r1, l2, r2); 
		int s = Seg.qry(rt[r1], 1, n, l2, r2) - Seg.qry(rt[l1 - 1], 1, n, l2, r2); 
		printf(s ? "1\n" : "0\n"); 
	}
	return 0;
}


http://www.kler.cn/news/355946.html

相关文章:

  • 高级交换基础
  • day48 图论章节刷题Part01(深搜理论基础、98. 所有可达路径、广搜理论基础)
  • Elixir 工具篇
  • Flink PostgreSQL CDC源码解读:深入理解数据流同步
  • Android一代整体壳简易实现和踩坑记录
  • Linux Ubuntu dbus CAPI ---- #include<dbus.h>出现“无法打开源文件dbus/xxx.h“的问题
  • 数据结构-5.8.由遍历序列构造二叉树
  • Python进阶--海龟绘图turtle库
  • Dungeon Crawler Grid Controller 地牢移动控制器
  • iOS模拟弱网步骤
  • 法律文书审查专项使用大模型实现
  • 在docker的容器内如何查看Ubuntu系统版本
  • Linux零基础教程学习(黑马)
  • Netty
  • MatrixOne助力江铜集团打造炉前智慧作业AIoT大数据系统
  • 分布式介绍
  • 框架一 Mybatis Spring SpringMVC(东西居多 后边的没怎么处理)
  • 05 django管理系统 - 部门管理 - 修改部门
  • Linux :at crontab简述
  • 【论文解读系列】EdgeNAT: 高效边缘检测的 Transformer