Kruskal重构树 + 倍增 + 主席树 25pts 求助
  • 板块P4197 Peaks
  • 楼主Mingjunyi
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/9/9 18:53
  • 上次更新2024/9/9 21:52:32
查看原帖
Kruskal重构树 + 倍增 + 主席树 25pts 求助
1088203
Mingjunyi楼主2024/9/9 18:53

只AC了第1个点,记录

#include<bits/stdc++.h>
using namespace std;
#define int long long
int rd() {
	int x = 0, w = 1;
	char ch = 0;
	while (ch < '0' || ch > '9') {
		if (ch == '-') w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return x * w;
}

void wt(int x) {
	static int sta[35];
	int f = 1;
	if(x < 0) f = -1,x *= f;
	int top = 0;
	do {
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if(f == -1) putchar('-');
	while (top) putchar(sta[--top] + 48);
}
const int N = 1e5+5,M = 5e5+5,maxn = N << 2;
int n,m,q,h[maxn],s[maxn],k,v[maxn];
array<int,3> e[M];
int head[maxn],nxt[maxn<<1],to[maxn<<1],cnt;
void init() {memset(head,-1,sizeof(head));}
int find(int x) {
	if(s[x] ^ x) s[x] = find(s[x]);
	return s[x];
}
void add(int u,int V) {
	nxt[cnt] = head[u];
	to[cnt] = V;
	head[u] = cnt++;
}

void kruskal() {
	k = n;
	int tot = 0;
	for(int i = 0;i<maxn;i++) s[i] = i;
	sort(e + 1,e + m + 1);
	for(int i = 1;i<=m;i++) {
		int fx = find(e[i][1]),fy = find(e[i][2]);
		if(fx ^ fy) {
			s[fx] = s[fy] = ++k;
			add(fx,k);add(fy,k);
			add(k,fx);add(k,fy);
			v[k] = e[i][0];
			tot++;
			if(tot == n - 1) break;
		}
	}
}

int fa[maxn][21],hd[maxn][21],L[maxn],R[maxn],tot;
int rt[maxn],lst[maxn];
namespace sgt{
#define mid ((pl + pr) >> 1)
int rot,siz[N*50],ls[N*50],rs[N*50];
int update(int f,int pl,int pr,int x) {
	int rt = ++rot;
	ls[rt] = ls[f];
	rs[rt] = rs[f];
	siz[rt] = siz[f] + 1;
	if(pl < pr) {
		if(x <= mid) ls[rt] = update(ls[f],pl,mid,x);
		else rs[rt] = update(rs[f],mid+1,pr,x);
	}
	return rt;
}

int query(int x,int y,int pl,int pr,int K) {
	if(siz[y] - siz[x] < K) return -1;
	if(pl == pr) return pl;
	int sz = siz[rs[y]] - siz[rs[x]];
	if(K <= sz) return query(rs[x],rs[y],mid + 1,pr,K);
	else return query(ls[x],ls[y],pl,mid,K - sz);
}

}

void dfs(int x,int f) {
	fa[x][0] = f;hd[x][0] = v[fa[x][0]];
	bool leaf = true;
	for(int i = head[x];~i;i = nxt[i]) {
		int y = to[i];
		if(y ^ f) {
			leaf = false;
			dfs(y,x);
			L[x] = min(L[x],L[y]);
			R[x] = max(R[x],R[y]);
		}
	}
	if(leaf) {
		R[x] = L[x] = ++tot;
		rt[tot] = sgt::update(rt[tot - 1],1,N,h[x]);
	}
}


signed main() {
	init();
    n = rd(),m = rd(),q = rd();
	for(int i = 1;i<=n;i++) h[i] = rd();
	for(int i = 1;i<=m;i++) 
		e[i][1] = rd(),e[i][2] = rd(),e[i][0] = rd();
	for(int i = 1;i<=n;i++)
		lst[i] = h[i];
	sort(lst + 1,lst + n + 1);
	int top = unique(lst + 1,lst + n + 1) - lst - 1;
	for(int i = 1;i<=n;i++)
		h[i] = lower_bound(lst + 1,lst + top + 1,h[i]) - lst;
	kruskal();
	memset(L,0x3f,sizeof(L));
	memset(hd,0x3f,sizeof(hd));
	v[0] = 0x3f3f3f3f3f3f3f3fLL;
	dfs(k,0);
	for(int x = 1;x<=k;x++)
		for(int i = 1;i<=20;i++) {
			fa[x][i] = fa[fa[x][i - 1]][i - 1]; 
			hd[x][i] = hd[fa[x][i - 1]][i - 1];
		}
	while(q--) {
		int S = rd(),x = rd(),k = rd();
		for(int i = 20;i >= 0;i--) 
			if(hd[S][i] <= x) 
				S = fa[S][i];
		int ans = sgt::query(rt[L[S] - 1],rt[R[S]],1,N,k);
		if(ans == -1) puts("-1");
		else wt(lst[ans]),putchar('\n');
	}

	return 0;
}

2024/9/9 18:53
加载中...