RE15pts求助
查看原帖
RE15pts求助
253527
GuideZombies楼主2023/3/18 13:20
#include <bits/stdc++.h>
typedef long long ll;
using std::sort;
using std::swap;
using std::min; using std::max;
#define l(p) tree[p].l
#define r(p) tree[p].r
#define s(p) tree[p].sum
#define ls(p) tree[p].lson
#define rs(p) tree[p].rson
#define INF INT_MAX
#define rd() read<int>()
#define E(i, l, r) for (int i = l; i <= r; ++ i)
template <typename T>
inline T read() {
  T x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  return f ? -x : x;
}
const int N = 2e5 + 5;
int n, m, q;
int root[N * 2], cnt;
int gg[N * 2];
struct Tree {
  int idx, cnt;
  int val[N * 2];
  int h[N * 2];
  int fa[N * 2];
  int an[N * 2][30];
  int e[N * 4], ne[N * 4];
  int cal, dfn[N * 4], sts[N * 4][2];
  Tree () {
    idx = 0;
    cnt = n;
    E(i, 1, n * 2)
      fa[i] = i;
    memset(h, -1, sizeof h);
    memset(an, 0, sizeof an);
    memset(val, 0, sizeof val);
  }
  void clear() {
    idx = 0;
    cnt = n;
    E(i, 1, n * 2)
      fa[i] = i;
    memset(h, -1, sizeof h);
    memset(an, 0, sizeof an);
    memset(val, 0, sizeof val);
  }
  int getfa(int x) {
    if (x == fa[x]) return x;
    return fa[x] = getfa(fa[x]);
  }
  void add(int x, int y) {
    ne[idx] = h[x];
    e[idx] = y;
    h[x] = idx ++;
//    std::cout << x << ' ' << h[x] << '\n';
  }
  void dfs(int cur, int fa) {
  	if (cur <= n) {
  		dfn[++ cal] = cur;
  		sts[cur][0] = cal;
		}
    else
    	sts[cur][0] = INF;
    E(i, 1, 20)
      an[cur][i] = an[an[cur][i - 1]][i - 1];
//    std::cout << cur << ' ' << fa << ' ' << h[cur] << "a\n"; 
    for (int i = h[cur]; ~i; i = ne[i]) {
//  	std::cout << cur << ' ' << fa << ' ' << e[i] << '\n';
      int go = e[i];
      if (go == fa) continue;
//      std::cout << cur << ' ' << go << ' ' << val[go] << '\n';
      dfs(go, cur);
    	sts[cur][0] = min(sts[cur][0], sts[go][0]);
    }
    sts[cur][1] = cal;
//    std::cout << cur << 'c' << sts[cur][0] << ' ' << sts[cur][1] << '\n';
  }
} Kti, Kta;
struct Node {
	int l, r;
	int lson, rson;
	int sum;
} tree[N * 8];
struct Edge {
  int x, y;
} edgeset[N];
bool cmpMin(Edge lhs, Edge rhs) {
  return lhs.y < rhs.y;
}
bool cmpMax(Edge lhs, Edge rhs) {
  return lhs.x > rhs.x;
}
void KruskalMin() {
  Kti.clear();
  sort(edgeset + 1, edgeset + m + 1, cmpMin);
  for (int i = 1; i <= m; ++ i) {
    Edge cur = edgeset[i];
    int u = cur.x, v = cur.y;
    int x = Kti.getfa(u), y = Kti.getfa(v);
    if (x != y) {
      Kti.val[++ Kti.cnt] = v;
//    	std::cout << u << ' ' << v << ' ' << x << ' ' << y << ' ' << Kti.cnt << ' ' << Kti.fa[Kti.cnt] << '\n';
      Kti.add(x, Kti.cnt); Kti.add(Kti.cnt, x);
      Kti.add(y, Kti.cnt); Kti.add(Kti.cnt, y);
      Kti.fa[x] = Kti.fa[y] = Kti.cnt;
      Kti.an[x][0] = Kti.an[y][0] = Kti.cnt;
    }
  }
  Kti.dfs(Kti.cnt, 0);
}
void KruskalMax() {
  Kta.clear();
  sort(edgeset + 1, edgeset + m + 1, cmpMax);
  for (int i = 1; i <= m; ++ i) {
    Edge cur = edgeset[i];
    int u = cur.x, v = cur.y;
    int x = Kta.getfa(u), y = Kta.getfa(v);
    if (x != y) {
      Kta.val[++ Kta.cnt] = u;
//    	std::cout << u << ' ' << v << ' ' << x << ' ' << y << ' ' << cnt << ' ' << Kta.fa[cnt] << '\n';
      Kta.add(x, Kta.cnt); Kta.add(Kta.cnt, x);
      Kta.add(y, Kta.cnt); Kta.add(Kta.cnt, y);
      Kta.fa[x] = Kta.fa[y] = Kta.cnt;
      Kta.an[x][0] = Kta.an[y][0] = Kta.cnt;
    }
  }
  Kta.dfs(Kta.cnt, 0);
}
void build(int p, int l, int r) {
	cnt = max(cnt, p);
	l(p) = l; r(p) = r; s(p) = 0;
//	std::cout << p << ' ' << l << ' ' << r <<'\n';
	if (l == r) return;
	int mid = l + r >> 1;
	ls(p) = p << 1; rs(p) = ls(p) + 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
}
void insert(int cur, int last, int x) {
//	std::cout << cur << ' ' << last << ' ' << x << ' ' << l(last) << ' ' << r(last) << '\n';
	l(cur) = l(last); r(cur) = r(last);
	s(cur) = s(last) + 1;
	if (l(last) == r(last)) return;
	int mid = (l(cur) + r(cur)) / 2;
	if (x <= mid) {
		rs(cur) = rs(last);
		ls(cur) = ++ cnt;
		insert(ls(cur), ls(last), x);
	}
	else {
		ls(cur) = ls(last);
		rs(cur) = ++ cnt;
		insert(rs(cur), rs(last), x);
	}
}
int query(int lt, int rt, int l, int r) {
//	std::cout << l(lt) << 'q' <<r(lt) << ' ' << s(lt) << ' ' << s(rt) << '\n';
	if (l(lt) > r || r(lt) < l) return 0;
	if (l <= l(lt) && r(lt) <= r) return s(rt) - s(lt);
	return query(ls(lt), ls(rt), l, r) + query(rs(lt), rs(rt), l, r);
}
int main() {
  n = rd();
  m = rd();
  q = rd();
  E(i, 1, m) {
    int x, y;
		x = rd(); y = rd();
    ++ x; ++ y;
    if (x > y) swap(x, y);
    edgeset[i] = {x, y};
  }
  KruskalMin();
  KruskalMax();
  E(i, 1, n)
  	gg[i] = Kta.sts[Kti.dfn[i]][0];
//  E(i, 1, n)
//  	std::cout << Kti.dfn[i] << ' ';
//  puts("");
//  E(i, 1, n)
//  	std::cout << Kta.dfn[i] << ' ';
//  puts("");
//  E(i, 1, n)
//  	std::cout << gg[i] << ' ';
//  puts("");
  build(1, 1, n); root[0] = 1;
  E(i, 1, Kti.cnt) {
  	root[i] = ++ cnt;
  	insert(root[i], root[i - 1], gg[i]);
	}
	Kti.val[0] = INF;
  while (q --) {
		int s, t, L, R;
		s = rd(); t = rd();
		L = rd(); R = rd();
		++ s; ++ t;
		++ L; ++ R;
		for (int i = 20; i >= 0; -- i)
			if (Kta.val[Kta.an[s][i]] >= L)
				s = Kta.an[s][i];
		for (int i = 20; i >= 0; -- i)
			if (Kti.val[Kti.an[t][i]] <= R)
				t = Kti.an[t][i];
		int l1, r1, l2, r2;
		l1 = Kta.sts[s][0];
		r1 = Kta.sts[s][1];
		l2 = Kti.sts[t][0];
		r2 = Kti.sts[t][1];
//		std::cout << s << ' ' <<t << ' ' << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 <<'\n';
		if (query(root[l2 - 1], root[r2], l1, r1) > 0)
			printf("1\n");
		else printf("0\n");
  }
  return 0;
}

RE处为主席树query,原因不清楚

2023/3/18 13:20
加载中...