BZOJ4543 Hotel加强版 (长链剖分优化dp)
有一个树形结构,每条边的长度相同,任意两个节点可以相互到达。选3个点。两两距离相等。有多少种方案?
神仙dp方程 啊,这就不写了
然后最难搞的指针的o1 转移
就是对于数组空间的分配很难理解,说是因为数组要移动,所以要开2被的空间,
但是我开了三倍。。。。
像这种转移方程是整体移位的,可以考虑长链剖分
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 #define ll long long 9 #define MAX 100100 10 inline int read() 11 { 12 int x=0,t=1;char ch=getchar(); 13 while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); 14 if(ch=='-')t=-1,ch=getchar(); 15 while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); 16 return x*t; 17 } 18 struct Line{int v,next;}e[MAX<<1]; 19 int h[MAX],cnt=1,n; 20 inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;} 21 int dep[MAX],hson[MAX],md[MAX]; 22 void dfs1(int u,int ff) 23 { 24 for(int i=h[u];i;i=e[i].next) 25 { 26 int v=e[i].v;if(v==ff)continue; 27 dfs1(v,u);md[u]=max(md[u],md[v]); 28 if(md[v]>md[hson[u]])hson[u]=v; 29 } 30 md[u]=md[hson[u]]+1; 31 } 32 ll *f[MAX],*g[MAX],tmp[MAX<<4],*id=tmp,ans; 33 void dfs(int u,int ff) 34 { 35 if(hson[u])f[hson[u]]=f[u]+1,g[hson[u]]=g[u]-1,dfs(hson[u],u); 36 f[u][0]=1;ans+=g[u][0]; 37 for(int i=h[u];i;i=e[i].next) 38 { 39 int v=e[i].v;if(v==ff||v==hson[u])continue; 40 f[v]=id;id+=md[v]<<2;g[v]=id;id+=md[v]<<2; 41 dfs(v,u); 42 for(int j=0;j<md[v];++j) 43 { 44 if(j)ans+=f[u][j-1]*g[v][j]; 45 ans+=g[u][j+1]*f[v][j]; 46 } 47 for(int j=0;j<md[v];++j) 48 { 49 g[u][j+1]+=f[u][j+1]*f[v][j]; 50 if(j)g[u][j-1]+=g[v][j]; 51 f[u][j+1]+=f[v][j]; 52 } 53 } 54 } 55 int main() 56 { 57 n=read(); 58 for(int i=1,u,v;i<n;++i)u=read(),v=read(),Add(u,v),Add(v,u); 59 dfs1(1,0);f[1]=id;id+=md[1]<<2;g[1]=id;id+=md[1]<<2; 60 dfs(1,0);printf("%lld\n",ans); 61 return 0; 62 }