萌新刚学 OI 求助卡常,lojAC,洛谷&uoj 95pts TLE
查看原帖
萌新刚学 OI 求助卡常,lojAC,洛谷&uoj 95pts TLE
350270
CatFromMars楼主2025/7/3 08:51

如题

#include <bits/stdc++.h>
#include "rts.h"
#define il inline
const int N = 3e5;
using namespace std;
// int explore(int,int);

namespace chain {
	bool used[N + 10];
	int n, T;
	vector <int> ord;
	void init(int nn, int tt) {
		n = nn, T = tt;
		for(int i = 2; i <= n; i++)
			ord.push_back(i);
		for(int t = 1; t <= 10; t++)
			random_shuffle(ord.begin(), ord.end());
		used[1] = 1;
		int L = 1, R = 1;
		for(int i = 0; i < ord.size(); i++) {
			if(used[ord[i]]) continue;
			int o = rand() % 2;
			int w = explore(((o == 0) ? R : L), ord[i]);
			if(!used[w]) {
				used[w] = 1;
				int x = w;
				while(x != ord[i])
					x = explore(x, ord[i]), 
					used[x] = 1;
				if(o == 0) R = ord[i];
				else L = ord[i];
			}
			else {
				w = explore(((o == 0) ? L : R), ord[i]);
				used[w] = 1;
				int x = w;
				while(x != ord[i])
					x = explore(x, ord[i]), 
					used[x] = 1;

				if(o == 1) R = ord[i];
				else L = ord[i];
			}
		}
	}
}
namespace tree {
	unordered_map <int, unordered_map <int, int> > M;
	vector <int> gra[N + 10];
	int fat[N + 10];
	vector <int> T[N + 10];
	int root = 0;
	int sz[N + 10];

	bool used[N + 10];
	int pot = 0;

	int n;
	il int getson(int u, int aim) {
		while(fat[u] != aim)
			u = fat[u];
		return u;
	}
	vector <int> dot;
	bool isin[N + 10], vis[N + 10];
	int cur[N + 10], tc = 0;
	il void getdot(int u) {
		cur[++tc] = u;
		isin[u] = 1;
		vis[u] = 0;
		for(int i = 0; i < T[u].size(); i++) {
			int v = T[u][i];
			getdot(v);
		}
		T[u].clear();
	}
	int siz[N + 10], mxz[N + 10];//in gra[] the siz
	int rem = 0, maxpart = N, nowroot = 0;
	il void getsiz(int u, int fa) {
		siz[u] = 1;
		mxz[u] = 0;
		for(int i = 0; i < gra[u].size(); i++) {
			int v = gra[u][i];
			if(vis[v] || !isin[v] || v == fa) continue;
			getsiz(v, u);
			siz[u] += siz[v];
			mxz[u] = max(mxz[u], siz[v]);
		}
	} 
	il int getroot(int u, int fa) {
		if(max(mxz[u], rem - siz[u]) <= rem / 2) return u;
		for(int i = 0; i < gra[u].size(); i++) {
			int v = gra[u][i];
			if(vis[v] || !isin[v] || v == fa) continue;
			int t = getroot(v, u);
			if(t != -1) return t;
		}
		return -1;
	}
	il void rb(int u) {
		vis[u] = 1;
		sz[u] = 1;
		for(int i = 0; i < gra[u].size(); i++) {
			int v = gra[u][i];
			if(vis[v] || !isin[v]) continue;
			getsiz(v, 0);
			rem = siz[v], maxpart = N, nowroot = getroot(v, 0);
			int ww = nowroot;
			T[u].push_back(ww);
			fat[ww] = u;
			rb(ww);
			sz[u] += sz[ww];
		}
	}
	il void rebuild(int u) {
		getdot(u);
		getsiz(u, 0);
		rem = siz[u], maxpart = N, nowroot = getroot(u, 0);
		if(nowroot != u && fat[u]) {
			vector <int> tmp = T[fat[u]];
			T[fat[u]].clear();
			for(int i = 0; i < tmp.size(); i++)
				if(tmp[i] != u) T[fat[u]].push_back(tmp[i]);
			T[fat[u]].push_back(nowroot);
			fat[nowroot] = fat[u];
		}
		if(!fat[u]) {
			sz[nowroot] = sz[root];
			root = nowroot;
			fat[nowroot] = 0;
		}
		rb(nowroot);
		for(int i = 1; i <= tc; i++) 
			isin[cur[i]] = vis[cur[i]] = 0;
		tc = 0;
	}
	int path[N + 10], tt = 0;
	il void find(int aim) {
		int x = root, bl = 0;
		while(1) {
			int z;
			if(M[x][aim]) z = M[x][aim];
			else z = M[x][aim] = explore(x, aim);
			bl = z;
			if(!used[z]) {
				gra[x].push_back(z);
				gra[z].push_back(x);
				T[x].push_back(z);
				fat[z] = x;
				used[z] = 1;
				break;
			}
			else
				x = getson(z, x);
		}
		tt = 0;
		x = bl;
		while(x) {
			path[++tt] = x;
			sz[x]++;
			x = fat[x];
		}
		for(int i = tt; i >= 2; i--) {
			int a = path[i], b = path[i - 1];
			if((double)(0.75 * sz[a]) < (double)(1.0 * sz[b])) {
				rebuild(a);
				return ;
			}
		}
	}
	void init(int nn) {
		n = nn;
		used[1] = 1;
		root = 1;
		sz[1] = 1;
		
		vector <int> ord;
		for(int i = 2; i <= n; i++)
			ord.push_back(i);
		random_shuffle(ord.begin(), ord.end());
		random_shuffle(ord.begin(), ord.end());

		for(int i = 0; i < ord.size(); i++) {
			int v = ord[i];
			while(!used[v]) 
				find(v);
		}
	}
}
void play(int n, int T, int dataType) {
	srand(20090725);
	if(dataType == 3) chain::init(n, T);
	else tree::init(n);
}

这个代码 95pts,loj 可以勉强卡过去,uoj 和 洛谷 都过不去,求助卡常 QAQ

2025/7/3 08:51
加载中...