萌新求助,洛谷 AC,UOJ TLE 75pts
查看原帖
萌新求助,洛谷 AC,UOJ TLE 75pts
482610
CEFqwq楼主2025/2/6 09:05
#include<bits/stdc++.h>
#define int long long
const int mod = 998244353;
using namespace std;
int n, m, tf[262150], dis[262150], suf[262150], f[262150][18], res;
inline int gdep(int u){//查深度 
	return floor(log2(u));
}
inline int gsiz(int u){//子树大小 
	return (1 << (n - gdep(u))) - 1;
}
inline int uvl(int u){//向父节点更新贡献 
	return suf[u] + tf[u] * gsiz(u);
}
inline int lca(int u, int v){//LCA
	if (u < v)
		swap(u, v);
	while (gdep(u) > gdep(v))
		u >>= 1;
	while (u != v){
		u >>= 1;
		v >>= 1;
	}
	return u;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	for (int i = 2; i < (1 << n); i++){
		cin >> tf[i];
		dis[i] = dis[i >> 1] + tf[i];
	}
	for (int i = (1 << n) - 1; i >= 1; i--){
		suf[i >> 1] += uvl(i);
	}
	memset(f, 0x3f, sizeof f); 
	while (m--){
		int u, v, w;
		cin >> u >> v >> w;
		for (int i = v; i >= u; i >>= 1)
			for (int j = i >> 1; j >= u; j >>= 1)//j->u->v->i
				f[i][gdep(j)] = min(f[i][gdep(j)], dis[v] - dis[i] + dis[j] - dis[u] + w);
	}
	for (int i = 1; i < (1 << n); i++)
		for (int j = i >> 1; j; j >>= 1)
			for (int adep = gdep(j) - 1; ~adep; adep--)
				f[i][adep] = min(f[i][adep], f[i][gdep(j)] + f[j][adep]);
	for (int i = (1 << n) - 1; i; i--){
		res = (res + suf[i]) % mod;
		for (int j = i; j != 1; j >>= 1)
			if (f[i][gdep(j) - 1] < 0x3f3f3f3f3f3f3f3fll)
				res = (res + f[i][gdep(j) - 1] % mod * (gsiz(j) + 1) % mod + uvl(j ^ 1)) % mod;
	}
	cout << res;
	return 0;
}
2025/2/6 09:05
加载中...