MX 入门赛 T3 90分求调
  • 板块学术版
  • 楼主mayike
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/14 17:33
  • 上次更新2024/7/14 18:28:52
查看原帖
MX 入门赛 T3 90分求调
1039406
mayike楼主2024/7/14 17:33
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e5+5;
int n,T,a[N],d[N],p[N][19],w[N][19],f[N][19];
vector<int>e[N];
void dfs(int u){
	for(int i=0;i<=18;i++)w[u][i]=a[u];
	for(int v:e[u]){
		d[v]=d[u]+1,p[v][0]=u;
		for(int i=1;i<=18;i++)
			if(p[v][i-1])p[v][i]=p[p[v][i-1]][i-1];
		dfs(v);
		for(int i=1;i<=18;i++)w[u][i]+=w[v][i-1];
	}
}
int lca(int x,int y){
	if(d[x]<d[y])swap(x,y);
	for(int i=18;i>=0;i--)
		if(d[x]-(1<<i)>=d[y])x=p[x][i];
	if(x==y)return x;
	for(int i=18;i>=0;i--)
		if(p[x][i]&&p[x][i]!=p[y][i])x=p[x][i],y=p[y][i];
	return p[x][0];
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>T;
	for(int i=1;i<=(1<<n)-1;i++)cin>>a[i],e[i/2].push_back(i);
	dfs(1);
	for(int u=2;u<=(1<<n)-1;u++)
		for(int i=1;i<=18;i++)f[u][i]=f[p[u][0]][i-1]+w[p[u][0]][i-1]-(i>=2?w[u][i-2]:0);
	while(T--){
		int x,y,z,k,s,q,x1,x2,o;
		cin>>x>>y>>k;
		if(k>=2*(n-1))cout<<w[1][18]<<"\n";
		else{
			z=lca(x,y),s=d[x]+d[y]-2*d[z];
			if(k<(s+1)/2){
				cout<<"0\n";
				continue;
			}
			if(s&1){
				s/=2,q=s;
				if(s<d[x]-d[z]){
					x1=x;
					while(s)s--,x1=p[x1][0];
				}else{
					x1=y;
					while(s)s--,x1=p[x1][0];
				}x2=p[x1][0];
				cout<<f[x2][k-q-1]+w[x2][k-q-1]-(k-q-2>=0?w[x1][k-q-2]:0)+w[x1][k-q-1]<<"\n";
			}else{
				s/=2,q=s;
				if(s<=d[x]-d[z]){
					o=x;
					while(s)s--,o=p[o][0];
				}else{
					o=y;
					while(s)s--,o=p[o][0];
				}cout<<f[o][k-q]+w[o][k-q]<<"\n";
			}
		}
	}
	return 0;
}

比较神奇,错了最后一个点

2024/7/14 17:33
加载中...