bzoj4515 [Sdoi2016] Game marking permanent line segment tree + chain section + difference

Another better difference in the path problem on the tree is to use the information of the root node. .

The form of the question is obviously a linear function, so I thought of maintaining the minimum value of the linear function

The ascending path is: A(d[x]-d[o])+B = -Ad[o]+(B-Ad[x]);

Descent path: A(d[x]+d[o]-2*d[lca])+B = Ad[o]+(B+A(d[o]-2*d[lca]))

Maintain new functions and check them separately when you query. . Because you need interval answers, you need up

No need to down if the mark is permanent

Note:

1. Pay attention to distinguish the original tree and the line segment tree

2. Note that the content of the query is outside and within the scope

3. Pay attention to the order of operations

4. Pay attention to long long 

5. Pay attention to the correspondence between d and dui

code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 100005
#define ll long long
bool cz[N<<2];
int n,m,fu[N],sz[N],zhong[N<<1],tot,hou[N<<1],xia[N],wz[N],top[N],hson[N],cnt,op,lca,x,y,i,dui[N];
ll v[N<<1],d[N],a,b,c,kk[N<<2],bb[N<<2],A,B,ans,minn[N<<2];
void jian(int a,int b,ll c)
{
	++tot;hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,v[tot]=c;	
}
void jia(int a,int b,ll c)
{
	jian(a,b,c);
	jian(b,a,c);
}
void dfs1(int o,int fa,ll dis)
{
	sz[o]=1;
	d[o]=dis;
	fu[o]=fa;
	int i,nd;
	for(i=xia[o];i!=-1;i=hou[i])
	{
		nd=zhong[i];
		if(nd==fa)continue;
		dfs1(nd,o,dis+v[i]);
		if(sz[hson[o]]<sz[nd])hson[o]=nd;
		sz[o]+=sz[nd];
	}	
}
void dfs2(int o,int tap)
{
	top[o]=tap;
	int i,nd;
	wz[o]=++cnt;
	dui[cnt]=o;
	if(hson[o])dfs2(hson[o],tap);
	for(i=xia[o];i!=-1;i=hou[i])
	{
		nd=zhong[i];
		if(nd==fu[o]||nd==hson[o])continue;
		dfs2(nd,nd);	
	}
}
void up(int o,ll l,ll mid,ll r)
{
	minn[o]= cz[o]? min(kk[o]*d[dui[l]]+bb[o],kk[o]*d[dui[r]]+bb[o]):123456789123456789  ;
	minn[o]=min(min(minn[o<<1],minn[o<<1|1]),minn[o]);
}
void gai(int o,int  l,int  r)
{int mid=(l+r)/2;
	if(op==1)//上升 
	{
if(a<=l&&r<=b)
{
if(cz[o]==0||(kk[o]*d[dui[l]]+bb[o] >  -A*d[dui[l]]+(B+A*d[x])  && kk[o]*d[dui[r]]+bb[o] >  -A*d[dui[r]]+(B+A*d[x]) ))
{
	cz[o]=1;
	kk[o]=-A;
	bb[o]=B+A*d[x];
	minn[o]=min(minn[o],min( -A*d[dui[l]]+(B+A*d[x]),-A*d[dui[r]]+(B+A*d[x])));
	return ;
}
if(kk[o]*d[dui[l]]+bb[o] <=  -A*d[dui[l]]+(B+A*d[x])  && kk[o]*d[dui[r]]+bb[o] <=  -A*d[dui[r]]+(B+A*d[x]) )
{
	return ;
}
long double jd=1.0000000*((B+A*d[x])-bb[o])/(1.0000000*(kk[o]+A));
if(jd<=d[dui[mid]])
{
	gai(o<<1,l,mid);
	if(kk[o]*d[dui[r]]+bb[o] > - A*d[dui[r]]+(B+A*d[x]) )gai(o<<1|1,mid+1,r);
}else
{
	gai(o<<1|1,mid+1,r);
	if(kk[o]*d[dui[l]]+bb[o] >  -A*d[dui[l]]+(B+A*d[x]) )gai(o<<1,l,mid);	
}
}else
{
if(a<=mid)gai(o<<1,l,mid);
if(b>mid)gai(o<<1|1,mid+1,r);
}		
	}
	if(op==0)//下降
	{	
if(a<=l&&r<=b)
{
if(cz[o]==0||(kk[o]*d[dui[l]]+bb[o] >  A*d[dui[l]]+(B+A*(d[x]-2*d[lca]))  && kk[o]*d[dui[r]]+bb[o] >  A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) ))
{
	cz[o]=1;
	kk[o]=A;
	bb[o]=B+A*(d[x]-2*d[lca]);
	minn[o]=min(min(A*d[dui[l]]+(B+A*(d[x]-2*d[lca])),  A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) ),minn[o]);
	return ;
}
if(kk[o]*d[dui[l]]+bb[o] <=  A*d[dui[l]]+(B+A*(d[x]-2*d[lca]))  && kk[o]*d[dui[r]]+bb[o] <=  A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) )
{
	return ;
}
long double jd=1.0000000*(B+A*(d[x]-2*d[lca])-bb[o])/(1.0000000*(kk[o]-A));
if(jd<=d[dui[mid]])
{
	gai(o<<1,l,mid);
	if(kk[o]*d[dui[r]]+bb[o] >   A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) )gai(o<<1|1,mid+1,r);
}else
{
	gai(o<<1|1,mid+1,r);
	if(kk[o]*d[dui[l]]+bb[o] >  A*d[dui[l]]+(B+A*(d[x]-2*d[lca])) )gai(o<<1,l,mid);	
}
}else
{
if(a<=mid)gai(o<<1,l,mid);
if(b>mid)gai(o<<1|1,mid+1,r);
}		
	}
	if(op==2)
	{
if(cz[o])ans=min(min( d[dui[min(1ll*r,b)]]*kk[o]+bb[o], d[dui[max(1ll*l,a)]]*kk[o]+bb[o]    ),ans);
	if(a<=l&&r<=b)
	{		
ans=min(ans,minn[o]);
	return ;
}
		if(a<=mid)
		gai(o<<1,l,mid);		
		if(b>mid)
		gai(o<<1|1,mid+1,r);	
	}
if(l!=r)up(o,l,mid,r);	
}
int LCA(int x,int y)
{
	while(top[x]!=top[y])
	{
	if(d[top[x]]<d[top[y]])swap(x,y);
	x=fu[top[x]];
    }	
	if(d[x]>d[y])swap(x,y);
return x;
}
void work(int x,int y)
{  lca=LCA(x,y);
	while(top[x]!=top[lca])
	{
	a=wz[top[x]];b=wz[x];
	gai(1,1,n);
	x=fu[top[x]];
    }	
	a=wz[lca];b=wz[x];
	gai(1,1,n);
if(op==1)op=0;	
	while(top[y]!=top[lca])
	{
	a=wz[top[y]];b=wz[y];
	gai(1,1,n);
	y=fu[top[y]];
    }	
	a=wz[lca];b=wz[y];
	gai(1,1,n);
}
void csh(int o,int l,int r)
{
	minn[o]=123456789123456789;
	if(l==r)return ;
	int mid=(l+r)>>1;
	csh(o<<1,l,mid);
	csh(o<<1|1,mid+1,r);	
}
int main()
{
memset(xia,-1,sizeof(xia));
	scanf("%d%d",&n,&m);
	csh(1,1,n);
	for(i=1;i<n;i++)
	{
		scanf("%lld%lld%lld",&a,&b,&c);
		jia(a,b,c);
	}
	dfs1(1,1,0);
	dfs2(1,1);
	while(m--)
	{
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%lld%lld",&x,&y,&A,&B);
			work(x,y);
		}else
		{
			ans=123456789123456789;
			scanf("%d%d",&x,&y);
			work(x,y);
			printf("%lld\n",ans);
		}
	}
}


Guess you like

Origin blog.csdn.net/haobang866/article/details/79434951