笛卡尔树+倍增LCA WA 0pt 求调
查看原帖
笛卡尔树+倍增LCA WA 0pt 求调
779970
lunjiahao楼主2024/3/7 19:00
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+5;
int n,q,a[N],w[N],top,stk[N],ls[N],rs[N],root;
int dep[N],fa[N][19],ql[N],qr[N],qc[N],G;
ll S[N],ans[N],f[N][19],g[N][19];
void dfs1(int u,int fath)
{
	fa[u][0]=fath;
	for(int i=1;i<=18;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
	if(ls[u]) dep[ls[u]]=dep[u]+1,dfs1(ls[u],u);
	if(rs[u]) dep[rs[u]]=dep[u]+1,dfs1(rs[u],u);
	S[u]=max(S[ls[u]],S[rs[u]])+w[u];
}
int lca(int u,int v)
{
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=dep[u]-dep[v],j=0;i;i>>=1,j++)
		if(i&1) u=fa[u][j];
	if(u==v) return u;
	for(int i=18;i;i--)
		if(fa[u][i]!=fa[v][i])
			u=fa[u][i],v=fa[v][i];
	return fa[u][0];
}
void dfs2(int u)
{
	f[u][0]=w[u];
	if (G) g[u][0]=S[ls[u]]+w[u];
		else g[u][0]=S[rs[u]]+w[u];
	for (int i=1;i<=18;i++)
	{
		fa[u][i]=fa[fa[u][i-1]][i-1];
		if(!fa[u][i+1]) break;
		f[u][i]=f[u][i-1]+f[fa[u][i-1]][i-1];
		g[u][i]=max(f[fa[u][i-1]][i-1]+g[u][i-1],g[fa[u][i-1]][i-1]);
	}
	if(ls[u])
	{
		if(G) fa[ls[u]][0]=fa[u][0];
			else fa[ls[u]][0]=u;
		dfs2(ls[u]);
	}
	if(rs[u])
	{
		if (G) fa[rs[u]][0]=u;
			else fa[rs[u]][0]=fa[u][0];
		dfs2(rs[u]);
	}
}

ll calc(int u,int z)
{
	ll res=0;
	for(int i=18;i;i--)
		if(dep[fa[u][i]]>=dep[z])
		{
			res=max(res+f[u][i],g[u][i]);
			u=fa[u][i];
		}
	return res;
}
signed main()
{
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) scanf("%d",&w[i]);
	for(int i=1;i<=n;i++)
	{
		while(top&&a[stk[top]]>a[i]) fa[stk[top]][0]=ls[i]=stk[top--];
		if(top) fa[stk[top]][0]=rs[stk[top]]=i;
		stk[++top]=i;
	}
	root=stk[1];
	dep[root]=1;
	dfs1(root,0);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d",&ql[i],&qr[i]);
		qc[i]=lca(ql[i],qr[i]);
	}
	G=1;
	dfs2(root);
	for(int i=1;i<=q;i++)
		ans[i]=calc(ql[i],qc[i])+w[qc[i]];
	G=0;
	dfs2(root);
	for(int i=1;i<=q;i++)
		ans[i]=max(ans[i],calc(qr[i],qc[i])+w[qc[i]]);
	for(int i=1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}
2024/3/7 19:00
加载中...