求卡常
查看原帖
求卡常
333855
int233楼主2024/5/12 07:21

做法:自己想的分块+换根DP,复杂度 O(nn)O(n\sqrt{n}) 。

Code(开O2 TLE 三个点):

#include<iostream>
#include<vector> 
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long ll;
ll n,k,u,v,w,a[100005],ans,ret,s[100005],pat[200005],Fi[200005],vr,ids[100005],dep[100005],lgs[200005],blo,L[100005],R[100005],bel[100005],sum[100005],f[100005][2],fa[100005][25];
vector<pair<ll,ll> > G[100005];
pair<ll,ll> st[200005][25];
char buf[1<<20],*p1,*p2;
char getc(){
	if(p1==p2){
		p1=buf;
		p2=buf+fread(buf,1,1<<20,stdin);
		if(p1==p2){
			return EOF;
		}
	}
	return *p1++;
}
inline void dfs(ll x,ll fat){
	fa[x][0]=fat;
	dep[x]=dep[fat]+1;
	pat[++vr]=x;
	Fi[x]=vr;
	for(ll i=1;i<=lgs[dep[x]];i++){
		fa[x][i]=fa[fa[x][i-1]][i-1];
	}
	for(ll i=0;i<G[x].size();i++){
		if(G[x][i].first!=fat){
			s[G[x][i].first]=s[x]+G[x][i].second;
			dfs(G[x][i].first,x);
			pat[++vr]=x;
		}
	}
}
inline ll LCA(ll x,ll y){
	ll l,r,k;
	l=min(Fi[x],Fi[y]),r=max(Fi[x],Fi[y]);
	k=lgs[r-l+1];
	return min(st[l][k],st[r-(1<<k)+1][k]).second;
}
inline void dfs2(ll x,ll fat,ll o){
	sum[x]=(ids[x]<=o);
	for(ll i=0;i<G[x].size();i++){
		if(G[x][i].first!=fat){
			dfs2(G[x][i].first,x,o);
			f[x][0]+=f[G[x][i].first][0]+sum[G[x][i].first]*G[x][i].second;
			sum[x]+=sum[G[x][i].first];
		}
	}
}
inline void dfs3(ll x,ll fat,ll o){
	for(ll i=0;i<G[x].size();i++){
		if(G[x][i].first!=fat){
			f[G[x][i].first][1]=f[x][1]+f[x][0]-f[G[x][i].first][0]+(sum[1]-2*sum[G[x][i].first])*G[x][i].second;
			dfs3(G[x][i].first,x,o);
		}
	}
}
inline ll read(){
    ll x(0);
    char ch=getc();
    while(ch<'0'||ch>'9'){
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getc();
    }
    return x;
}
inline void write(ll x){
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
int main(){
	n=read(),k=read();
	for(ll i=1;i<=n-1;i++){
		u=read(),v=read(),w=read();
		G[u].push_back({v,w});
		G[v].push_back({u,w});
	}
	for(ll i=2;i<=n;i++){
		lgs[i]=lgs[i>>1]+1;
	}
	for(ll i=1;i<=n;i++){
		ids[i]=1e9;
	}
	dfs(1,0);
	for(ll i=2;i<=vr;i++){
		lgs[i]=lgs[i>>1]+1;
	}
	for(ll i=1;i<=vr;i++){
		st[i][0]={dep[pat[i]],pat[i]};
	}
	for(ll i=1;(1<<i)<=vr;i++){
		for(ll j=1;j+(1<<i)-1<=vr;j++){
			st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
		}
	}
	k++;
	a[1]=1;
	for(ll i=2;i<=k;i++){
		a[i]=read();
	}
	blo=int(sqrt(n))*7/2;
	for(ll i=1;i<=k;i++){
		bel[i]=(i-1)/blo+1;
		R[bel[i]]=i;
		ids[a[i]]=bel[i];
	}
	for(ll i=k;i>=1;i--){
		L[bel[i]]=i;
	}
	for(ll i=0;i<bel[k];i++){
		for(ll j=1;j<=n;j++){
			f[j][0]=0;
		}
		dfs2(1,0,i);
		dfs3(1,0,i);
		for(ll j=L[i+1];j<=R[i+1];j++){
			ret=f[a[j]][0]+f[a[j]][1];
			for(ll k=L[i+1];k<j;k++){
				ret+=s[a[j]]+s[a[k]]-s[LCA(a[j],a[k])]*2;
				//cout<<j<<" "<<k<<" "<<ret<<"IAKIOI"<<endl;
			}
			ans+=ret;
			if(j>=2){
				write(ans*2);
				printf("\n");
			}
		}
	}
	return 0;
}
2024/5/12 07:21
加载中...