RE求助
查看原帖
RE求助
685964
shuqiang楼主2024/10/30 13:52
#include<iostream>

using namespace std;
typedef long long ll;

const int N = (1 << 20) + 10;
int n, m, w[N], x, y, k, dep[N];
ll f[N][50], g[N][50];

int lca(int u, int v){
	if(dep[u] < dep[v]) v >>= dep[v] - dep[u];
	if(dep[u] > dep[v]) u >>= dep[u] - dep[v];
	while(u != v) {u >>= 1; v >>= 1;}
	return u;
}

int mid(int u, int v, bool & b){
	int w = lca(u, v);
	if(dep[u] < dep[v]) swap(u, v);
	u >>= dep[v] - dep[w]; v >>= dep[v] - dep[w];
	if((dep[u] - dep[v]) & 1){
		b = 1;
		return u >> ((dep[u] - dep[v]) >> 1);
	}
	else{
		b = 0;
		return u >> ((dep[u] - dep[v]) >> 1);
	}
}

int dis(int u, int v){
	int w = lca(u, v);
	return dep[u] + dep[v] - 2 * dep[w];
}

void get_f(int u){
	if(dep[u] == 0) return;
	get_f(u*2); get_f(u*2+1);
	for(int i = 1; i <= 40; i++){
		f[u][i] = f[u*2][i-1] + f[u*2+1][i-1] + w[u];
	}
	f[u][0] = w[u];
}

void get_g(int u){
	if(dep[u] == 0) return;
	g[u][0] = w[u];
	if(u == 1) for(int i = 1; i <= 40; i++) g[u][i] = w[u];
	else{
		for(int i = 1; i <= 40; i++){
			g[u][i] = g[u/2][i-1] + f[u/2][i-1] - f[u][i-2] - w[u/2] + w[u];
		}
	}
	get_g(u*2); get_g(u*2+1);
}

int main(){
	cin >> n >> m;
	for(int i = 1; i < (1 << n); i++) dep[i] = dep[i/2] + 1;
	for(int i = 1; i < (1 << n); i++) cin >> w[i];
	get_f(1);
	get_g(1);
	while(m--){
		cin >> x >> y >> k;
		bool b; int mid1 = mid(x, y, b), mid2;
		if(b){
			mid2 = mid1 >> 1;
			if(dis(mid1, x) + dis(mid2, y) > dis(mid1, y) + dis(mid2, x)) swap(x, y);
			k -= dis(mid1, x)+1;
			if(k < 0) cout << 0 << '\n';
			else if(k > 40) cout << f[1][40] << '\n';
			else cout << f[mid1][k] + f[mid2][k] - f[mid1][k-1] + g[mid2][k] - w[mid2] << '\n';
		}
		else{
			if(k < dis(mid1, x)) cout << 0 << '\n';
			else if(k > 40) cout << f[1][40] << '\n';
			else cout << f[mid1][k - dis(mid1, x)] + g[mid1][k - dis(mid1, x)] - w[mid1] << '\n';
		}
	}
	return 0;
}

这个代码在洛谷交是 AC,但在梦熊交是 RE。

2024/10/30 13:52
加载中...