传送门

无脑暴力+O2=AC

题目要统计距离两两相等的三个点的组数,这三个点之间显然有一个点,并且这三个点到这个点的距离都相同.所以枚举中间这个点作为根,然后bfs整棵树,对于每一层,把以根的某个儿子的子树中在这一层点的数量统计出来,那么这样三元组的数量就是在这些点里面选3个点,并且分别来自不同子树的方案,\(f_{i,0/1/2/3}\)即可

详见代码

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define LL long long
  4. #define il inline
  5. #define re register
  6. using namespace std;
  7. const int N=5000+10;
  8. il int rd()
  9. {
  10. int x=0,w=1;char ch=0;
  11. while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  12. while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  13. return x*w;
  14. }
  15. LL ans,f[N][4];
  16. int to[N<<1],nt[N<<1],hd[N],dg[N],tot=1,a[N];
  17. bool v[N];
  18. il void add(int x,int y)
  19. {
  20. ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++dg[x];
  21. ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot,++dg[y];
  22. }
  23. int n,m;
  24. int main()
  25. {
  26. n=rd();
  27. for(int i=1;i<n;++i) add(rd(),rd());
  28. for(int i=0;i<=n;++i) f[i][0]=1;
  29. queue<int> id[2],q[2];
  30. for(int i=1;i<=n;++i)
  31. {
  32. memset(v,0,sizeof(v));
  33. v[i]=1;
  34. while(!id[0].empty()) id[0].pop();
  35. while(!id[1].empty()) id[1].pop();
  36. while(!q[0].empty()) q[0].pop();
  37. while(!q[1].empty()) q[1].pop();
  38. m=dg[i];
  39. int nw=1,la=0;
  40. for(int j=hd[i],k=1;j;j=nt[j],++k) id[0].push(k),q[0].push(to[j]);
  41. while(!q[la].empty())
  42. {
  43. memset(a,0,4*(m+1));
  44. while(!q[la].empty())
  45. {
  46. int k=id[la].front(),x=q[la].front();
  47. id[la].pop(),q[la].pop();
  48. ++a[k],v[x]=true;
  49. for(int j=hd[x];j;j=nt[j])
  50. {
  51. int y=to[j];
  52. if(!v[y]) id[nw].push(k),q[nw].push(y);
  53. }
  54. }
  55. for(int j=1;j<=m;++j)
  56. {
  57. for(int k=1;k<=3;++k) f[j][k]=f[j-1][k]+f[j-1][k-1]*a[j];
  58. }
  59. ans+=f[m][3];
  60. swap(nw,la);
  61. }
  62. }
  63. printf("%lld\n",ans);
  64. return 0;
  65. }

正解是长链剖分

咕咕咕

传送门

其实上面那个dp比较沙雕,可以直接设\(f_{i,j}\)为点\(i\)子树内到\(i\)距离为\(j\)的点个数,\(g_{i,j}\)为点\(i\)子树内,到lca距离为\(d\),且这个lca到\(i\)距离为\(d-j\)的点对个数,然后转移就是

\[ans=\sum_{x}g_{x,0}+\sum_{y=son_x}\sum_{j}f_{x,j-1}*g_{y,j}$$$$f_{x,j}=\sum_{y=son_x} f_{y,j-1}$$$$g_{x,j}=\sum_{y=son_x,z=son_x,y<z} f_{y,j-1}*f_{z,j-1}+\sum_{y=son_x} g_{y,j+1}
\]

对整棵树长链剖分之后,那么转移时就直接可以继承重儿子的信息,轻儿子直接暴力合并,因为每个点只会在链顶被暴力合并上去,所以复杂度是\(O(n)\)的

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define il inline
  4. #define re register
  5. using namespace std;
  6. const int N=100000+10;
  7. il int rd()
  8. {
  9. int x=0,w=1;char ch=0;
  10. while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  11. while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  12. return x*w;
  13. }
  14. int to[N<<1],nt[N<<1],hd[N],tot=1;
  15. il void add(int x,int y)
  16. {
  17. ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
  18. ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
  19. }
  20. int n,m;
  21. int ff[N],de[N],dpt[N],son[N];
  22. LL *f[N],*g[N],rbq[N<<3],*uc=rbq,ans;
  23. void dfs1(int x)
  24. {
  25. dpt[x]=de[x];
  26. for(int i=hd[x];i;i=nt[i])
  27. {
  28. int y=to[i];
  29. if(y==ff[x]) continue;
  30. ff[y]=x,de[y]=de[x]+1,dfs1(y),dpt[x]=max(dpt[x],dpt[y]);
  31. if(dpt[son[x]]<dpt[y]) son[x]=y;
  32. }
  33. }
  34. void dd(int x)
  35. {
  36. if(son[x]) f[son[x]]=f[x]+1,g[son[x]]=g[x]-1,dd(son[x]);
  37. f[x][0]=1,ans+=g[x][0];
  38. for(int i=hd[x];i;i=nt[i])
  39. {
  40. int y=to[i];
  41. if(y==ff[x]||y==son[x]) continue;
  42. f[y]=uc,uc+=(dpt[y]-de[x]+1)<<1,g[y]=uc,uc+=(dpt[y]-de[x]+1)<<1;
  43. dd(y);
  44. for(int j=0;j<dpt[y]-de[x];++j)
  45. {
  46. if(j) ans+=f[x][j-1]*g[y][j];
  47. ans+=g[x][j+1]*f[y][j];
  48. }
  49. for(int j=0;j<dpt[y]-de[x];++j)
  50. {
  51. g[x][j+1]+=f[x][j+1]*f[y][j];
  52. if(j) g[x][j-1]+=g[y][j];
  53. f[x][j+1]+=f[y][j];
  54. }
  55. }
  56. }
  57. int main()
  58. {
  59. n=rd();
  60. for(int i=1;i<n;++i) add(rd(),rd());
  61. de[1]=1,dfs1(1);
  62. f[1]=uc,uc+=(dpt[1]+1)<<1,g[1]=uc,uc+=(dpt[1]+1)<<1;
  63. dd(1);
  64. printf("%lld\n",ans);
  65. return 0;
  66. }

luogu P3565 [POI2014]HOT-Hotels的更多相关文章

  1. Luogu P3577 [POI2014]TUR-Tourism

    Luogu P3577 [POI2014]TUR-Tourism 题目链接 题目大意:给出一张\(n\)个点,\(m\)条边的无向图,保证任意两点之间没有点数超过\(10\)的简单路径.选择第\(i\ ...

  2. luogu P3567 [POI2014]KUR-Couriers

    二次联通门 : luogu P3567 [POI2014]KUR-Couriers MMP 指针 RE + MLE + WA..... 不得已...向黑恶的数组实力低头 /* 指针 */ #inclu ...

  3. 主席树||可持久化线段树||BZOJ 3524: [Poi2014]Couriers||BZOJ 2223: [Coci 2009]PATULJCI||Luogu P3567 [POI2014]KUR-Couriers

    题目:[POI2014]KUR-Couriers 题解: 要求出现次数大于(R-L+1)/2的数,这样的数最多只有一个.我们对序列做主席树,每个节点记录出现的次数和(sum).(这里忽略版本差值问题) ...

  4. P3565 [POI2014]HOT-Hotels

    题目描述 There are nn towns in Byteotia, connected with only n-1n−1 roads. Each road directly links two ...

  5. [luogu]P3572 [POI2014]PTA-Little Bird(单调队列)

    P3572 [POI2014]PTA-Little Bird 题目描述 In the Byteotian Line Forest there are nn trees in a row. On top ...

  6. luogu P3576 [POI2014]MRO-Ant colony

    传送门 一群蚂蚁能被吃,也就是走到指定边的两端点之一要走到另一端点时有\(k\)只,我们可以从这两端点逆推,记两个值为走到某个点时最后会被吃掉\(k\)只蚂蚁的蚂蚁数量范围,式子下面有,很好理解(雾) ...

  7. Luogu P3579 [POI2014]PAN-Solar Panels

    题目大意: 给出T组询问,每组询问给出四个数a,b,c,d,每次询问满足a<=x<=b,c<=y<=d的gcd(x,y)的最大值 首先可以想到如果存在gcd(x,y)=k,那么 ...

  8. luogu P3572 [POI2014]PTA-Little Bird |单调队列

    从1开始,跳到比当前矮的不消耗体力,否则消耗一点体力,每次询问有一个步伐限制,求每次最少耗费多少体力 #include<cstdio> #include<cstring> #i ...

  9. luogu P3572 [POI2014]PTA-Little Bird

    题目描述 从1开始,跳到比当前矮的不消耗体力,否则消耗一点体力,每次询问有一个步伐限制,求每次最少耗费多少体力 单调队列优化动态规划 #include<cstdio> #include&l ...

随机推荐

  1. jdbc,mybatis,hibernate各自有优缺点以及区别

    JDBC: 我们平时使用jdbc进行编程,大致需要下面几个步骤: 1,使用jdbc编程需要连接数据库,注册驱动和数据库信息 2,操作Connection,打开Statement对象 3,通过State ...

  2. Borg Maze POJ - 3026 (BFS + 最小生成树)

    题意: 求把S和所有的A连贯起来所用的线的最短长度... 这道题..不看discuss我能wa一辈子... 输入有坑... 然后,,,也没什么了...还有注意 一次bfs是可以求当前点到所有点最短距离 ...

  3. Leetcode 326.3的幂 By Python

    给定一个整数,写一个函数来判断它是否是 3 的幂次方. 示例 1: 输入: 27 输出: true 示例 2: 输入: 0 输出: false 示例 3: 输入: 9 输出: true 示例 4: 输 ...

  4. MQTT——取消订阅报文和断开连接报文

    笔者已经把连接报文,订阅报文,发布报文都讲解了完了.而接下来就是取消订阅报文和断开连接报文.和其他的报文比较的话,他们显示非常简单.甚至笔者觉得可以不必要拿出来讲.只要看一下MQTT文档就没有什么不清 ...

  5. MATLAB:图像选取局部区域滤波(roicolor、roipoly、roifill、fspecial、roifilt2函数)

    对于某些特殊的图像处理,我们不希望将整张图都进行图像处理.这个时候就用到了roicolor.roipoly.roifill.fspecial.roifilt2函数.代码实现过程如下: close al ...

  6. apache 基本vhost配置 【目的及过程】

    转: apache 基本vhost配置 2012年04月18日 09:39:28 chamtianjiao 阅读数:74075     经常使用Apache虚拟主机进行开发和测试,但每次需要配置虚拟主 ...

  7. 洛谷 P4378 [USACO18OPEN]Out of Sorts S(树状数组求冒泡排序循环次数)

    传送门:Problem P4378 https://www.cnblogs.com/violet-acmer/p/9833502.html 要回宿舍休息了,题解明天再补吧. 题解: 定义一数组 a[m ...

  8. 二叉查找树(BST)、平衡二叉树(AVL树)

    二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于或等于根结点的数据域,右 ...

  9. 使用Nessus漏扫

    Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它.该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库.Nessus不同于传统的漏洞扫描软件,Nessus可同时在 ...

  10. 安装Cloudera manager Server步骤详解

    安装Cloudera manager Server步骤详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客主要是针对:https://www.cnblogs.com/yin ...