BZOJ2152 聪聪可可 点分治

此题明显可以点分治解决,对每层分治块递归子块,求出块内有多少距离%3=0,1,2的节点,与之前其他块的信息归并,

即ans+=f[0]*g[0]+f[1]*g[2]+f[2]*g[1],再把g加到f上面去即可

注意点分治求重心一定注意不要打错字母(打混x,y之类的)

注意此题题意诡异,点对要*2+n(单点也算,反过来算两次)

分母是n*n而不是n*(n-1)/2

#include
#include
using namespace std;
typedef long long LL;
const int Mn=200005;
struct Edge{int to,next,v;}w[Mn];
int n,cnt=0,h[Mn],s[Mn],minn,tg,sz,vst[Mn];
LL f[5],g[5],ans=0;
void AddEdge(int x,int y,int v){w[++cnt]=(Edge){y,h[x],v};h[x]=cnt;}
void init(){
	 int i,x,y,z;
	 scanf("%d",&n);
	 for(i=1;i


你可能感兴趣的:(点分治)