板子题目求助,跪求大佬指点
查看原帖
板子题目求助,跪求大佬指点
750803
_Revenge_楼主2022/8/18 14:17

思路:树链剖分

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef double db;

const int N=1e5+50;
const int M=1e5+50;
const int Mod=1e9+7;

inline ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

ll n,k;
ll top[N],siz[N],dep[N],id[N],wt[N],fa[N],son[N],res;
ll head[N],cnt;
struct edge{
	ll to,next;
}e[N<<1];
void add_edge(ll u,ll v){
	++cnt;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs1(ll u,ll p){
	fa[u]=p;
	dep[u]=dep[p]+1;
	siz[u]=1;
	int maxn=-1;
	for(int i=head[u];i;i=e[i].next){
		ll v=e[i].to;
		if(v==p) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>maxn) son[u]=v,maxn=siz[v];
	}
} 

void dfs2(ll u,ll topf){
	top[u]=topf;
	++res;
	id[u]=res;
	wt[res]=0;
	if(!son[u]) return;
	dfs2(son[u],topf);
	for(int i=head[u];i;i=e[i].next){
		ll v=e[i].to;
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}

ll ans[N<<2],lazy[N<<2];

ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
void push_up(ll p){ans[p]=max(ans[ls(p)],ans[rs(p)]);}

void build(ll p,ll l,ll r){
	lazy[p]=0;
	if(l==r){ans[p]=wt[l];return;}
	ll mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	push_up(p);
}

void change(ll p,ll l,ll r,ll add){
	ans[p]+=(r-l+1)*add;
	lazy[p]+=add;
}

void push_down(ll p,ll l,ll r){
	ll mid=(l+r)>>1;
	change(ls(p),l,mid,lazy[p]);
	change(rs(p),mid+1,r,lazy[p]);
	lazy[p]=0;
}

void update(ll nx,ll ny,ll l,ll r,ll p,ll k){
	if(nx<=l&&r<=ny){
		lazy[p]+=k;
		ans[p]+=(r-l+1)*k;
		return;
	}
	push_down(p,l,r);
	ll mid=(l+r)>>1;
	if(nx<=mid) update(nx,ny,l,mid,ls(p),k);
	if(ny>mid) update(nx,ny,mid+1,r,rs(p),k);
	push_up(p);
}

ll query(ll nx,ll ny,ll l,ll r,ll p){
	ll res=0;
	if(nx<=l&&r<=ny) return ans[p];
	push_down(p,l,r);
	ll mid=(l+r)>>1;
	if(nx<=mid) res=max(res,query(nx,ny,l,mid,ls(p)));
	if(ny>mid) res=max(res,query(nx,ny,mid+1,r,rs(p)));
	return res;
}

void update_range(ll x,ll y,ll k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(id[top[x]],id[x],1,n,1,k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(id[x],id[y],1,n,1,k);
}


int main()
{
	n=read(),k=read();
	for(int i=1;i<n;++i){
		ll u=read(),v=read();
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=k;++i){
		ll u=read(),v=read();
		update_range(u,v,1);
	}
	printf("%lld\n",query(1,n,1,n,1));
	return 0;
}

2022/8/18 14:17
加载中...