蒟蒻求助点分治
  • 板块学术版
  • 楼主cyfff
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/9/25 21:02
  • 上次更新2023/11/5 12:38:06
查看原帖
蒟蒻求助点分治
181437
cyfff楼主2020/9/25 21:02

P2634 TLE 40分,答案对的。之前用树形dp过了,为什么点分治过不了。

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int rd(){
	ri res=0,f=1;register char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())res=(res<<1)+(res<<3)+ch-48;
	return res*f;
}
int n,dep[20005],f[20005],vis[20005],sz[20005],rt,ans;
int hd[20005],cnt,now,nxt[40005],to[40005],vl[40005];
void add(int x,int y,int z){to[++cnt]=y;vl[cnt]=z;nxt[cnt]=hd[x];hd[x]=cnt;}
void zx(int k,int fa){
	f[k]=0;sz[k]=1;
	for(ri i=hd[k],j;i;i=nxt[i])
	if(!vis[j=to[i]]&&j!=fa){
		zx(j,k);sz[k]+=sz[j];
		f[k]=max(f[k],sz[j]);
	}
	f[k]=max(f[k],now-sz[k]);
	if(f[k]<f[rt])rt=k;
}
void ds(int k,int fa,int val){
	dep[val]++;
	for(ri i=hd[k],j;i;i=nxt[i])
	if(!vis[j=to[i]]&&j!=fa){
		zx(j,k);sz[k]+=sz[j];
		f[k]=max(f[k],sz[j]);
		ds(j,k,(val+vl[i])%3);
	}
}
int calc(int k,int val){
	dep[0]=dep[1]=dep[2]=0;ds(k,0,val%3);
	return dep[0]*dep[0]+2*dep[1]*dep[2];
}
void fz(int k){
	vis[k]=1;ans+=calc(k,0);
	for(ri i=hd[k],j;i;i=nxt[i])
	if(!vis[j=to[i]]){
		ans-=calc(j,vl[i]);
		rt=0;now=sz[j];
		zx(j,0);fz(rt);
	}
}
int main(){
	n=rd();
	for(ri i=1,x,y,z;i<n;++i){
		x=rd();y=rd();z=rd();
		add(x,y,z);add(y,x,z);
	}
	now=f[0]=n;zx(1,0);fz(rt);
	n*=n;rt=__gcd(ans,n);
	printf("%d/%d",ans/rt,n/rt);
	return 0;
}
2020/9/25 21:02
加载中...