题目大意

一棵树,每个节点的权为L[i]~R[i],一棵树的贡献为\(\sum\limits_{h_{i} = h_{j}, 1 \le i < j \le n}{dis(i,j)}\),其中\(dis(i,j)\)表示i到j路径上的边数

求\(\prod\limits_{i = 1}^{n} (r_{i} - l_{i} + 1)\)种不同取值的情况的贡献和

题解

一眼点分治

把一个点的子树上除该点的乘积加到对应区间上,查找就直接找对应区间

设S[i]表示\(\prod_{i\neq j}{R_i-L_i+1}\),W[i]表示\(\frac{1}{R_i-L_i+1}\)

那么在b点查询a时一种方案的贡献为\(S[a]*W[b]*(dis[a]+dis[b])\),拆开后为\(W[b]*S[a]*dis[a]+W[b]*dis[b]*S[a]\),维护S[a]*dis[a]与S[a]的和即可

线段树常数较大,所以要用树状数组

code

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #define fo(a,b,c) for (a=b; a<=c; a++)
  7. #define fd(a,b,c) for (a=b; a>=c; a--)
  8. #define add(a,b) a=((a)+(b))%1000000007
  9. #define max(a,b) (a>b?a:b)
  10. #define low(x) (x&-(x))
  11. #define mod 1000000007
  12. #define Mod 1000000005
  13. #define N 100000
  14. using namespace std;
  15. int a[200001][2];
  16. int tr[100001][4];
  17. bool Tr[100001];
  18. int d[100001];
  19. int ls[100001];
  20. int L[100001];
  21. int R[100001];
  22. int size[100001];
  23. bool bz[100001];
  24. int Fa[100001];
  25. long long S[100001];
  26. long long w[100001];
  27. int n,i,j,k,l,len,mn1,mn2,SIZE,tot;
  28. long long sum,ans,W,D,WD,find1,find2;
  29. void New(int x,int y)
  30. {
  31. ++len;
  32. a[len][0]=y;
  33. a[len][1]=ls[x];
  34. ls[x]=len;
  35. }
  36. long long qpower(long long a,int b)
  37. {
  38. long long ans=1;
  39. while (b)
  40. {
  41. if (b&1)
  42. ans=ans*a%mod;
  43. a=a*a%mod;
  44. b>>=1;
  45. }
  46. return ans;
  47. }
  48. void Change(int t,long long s1,long long s2)
  49. {
  50. long long S1=-s1*(t-1)%mod,S2=-s2*(t-1)%mod;
  51. while (t<=N)
  52. {
  53. if (!Tr[t])
  54. Tr[t]=1,d[++tot]=t;
  55. add(tr[t][0],s1);
  56. add(tr[t][1],S1);
  57. add(tr[t][2],s2);
  58. add(tr[t][3],S2);
  59. t+=low(t);
  60. }
  61. }
  62. void change(int l,int r,long long s1,long long s2)
  63. {
  64. Change(l,s1,s2);
  65. Change(r+1,-s1,-s2);
  66. }
  67. void Find(int t,int type)
  68. {
  69. int T=t;
  70. long long s1,S1,s2,S2;
  71. s1=S1=s2=S2=0;
  72. while (t)
  73. {
  74. add(s1,tr[t][0]);
  75. add(S1,tr[t][1]);
  76. add(s2,tr[t][2]);
  77. add(S2,tr[t][3]);
  78. t-=low(t);
  79. }
  80. add(find1,(s1*T+S1)%mod*type);
  81. add(find2,(s2*T+S2)%mod*type);
  82. }
  83. void find(int l,int r)
  84. {
  85. find1=find2=0;
  86. Find(r,1);
  87. Find(l-1,-1);
  88. }
  89. void dfs1(int fa,int t)
  90. {
  91. int i,mx=0;
  92. Fa[t]=fa;
  93. size[t]=1;
  94. for (i=ls[t]; i; i=a[i][1])
  95. if (!bz[a[i][0]] && a[i][0]!=fa)
  96. {
  97. dfs1(t,a[i][0]);
  98. size[t]+=size[a[i][0]];
  99. mx=max(mx,size[a[i][0]]);
  100. }
  101. mx=max(mx,SIZE-size[t]);
  102. if (mx<mn1)
  103. mn1=mx,mn2=t;
  104. }
  105. void dfs2(int fa,int t,int dis)
  106. {
  107. int i;
  108. W=w[t];D=dis;WD=W*D%mod;
  109. find(L[t],R[t]);
  110. add(ans,WD*find1+W*find2);
  111. for (i=ls[t]; i; i=a[i][1])
  112. if (!bz[a[i][0]] && a[i][0]!=fa)
  113. dfs2(t,a[i][0],dis+1);
  114. }
  115. void dfs3(int fa,int t,int dis)
  116. {
  117. int i;
  118. change(L[t],R[t],S[t],S[t]*dis%mod);
  119. for (i=ls[t]; i; i=a[i][1])
  120. if (!bz[a[i][0]] && a[i][0]!=fa)
  121. dfs3(t,a[i][0],dis+1);
  122. }
  123. void work(int t,int Size)
  124. {
  125. int i;
  126. SIZE=Size;
  127. mn1=Size;
  128. mn2=t;
  129. dfs1(0,t);
  130. t=mn2;
  131. bz[t]=1;
  132. // ---
  133. tot=0;
  134. change(L[t],R[t],S[t],0);
  135. for (i=ls[t]; i; i=a[i][1])
  136. if (!bz[a[i][0]])
  137. {
  138. dfs2(t,a[i][0],1);
  139. dfs3(t,a[i][0],1);
  140. }
  141. fo(i,1,tot)
  142. tr[d[i]][0]=tr[d[i]][1]=tr[d[i]][2]=tr[d[i]][3]=Tr[d[i]]=0;
  143. // ---
  144. for (i=ls[t]; i; i=a[i][1])
  145. if (!bz[a[i][0]] && a[i][0]!=Fa[t])
  146. work(a[i][0],size[a[i][0]]);
  147. if (Fa[t])
  148. work(Fa[t],Size-size[t]);
  149. }
  150. int main()
  151. {
  152. // freopen("f.in","r",stdin);
  153. // freopen("b.out","w",stdout);
  154. sum=1;
  155. scanf("%d",&n);
  156. fo(i,1,n)
  157. scanf("%d%d",&L[i],&R[i]),sum=(sum*(R[i]-L[i]+1))%mod,w[i]=qpower(R[i]-L[i]+1,Mod);
  158. fo(i,2,n)
  159. {
  160. scanf("%d%d",&j,&k);
  161. New(j,k);
  162. New(k,j);
  163. }
  164. fo(i,1,n)
  165. S[i]=sum*w[i]%mod;
  166. work(1,n);
  167. printf("%I64d\n",(ans+mod)%mod);
  168. }

CF1260F的更多相关文章

随机推荐

  1. 【ABAP系列】SAP ABAP 动态指针

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 动态指针   ...

  2. SSM项目——乐淘商城话述1.0

    乐淘商城 项目介绍 淘淘网上商城是一个综合性的B2C平台,类似京东商城.天猫商城.会员可以在商城浏览商品.下订单,以及参加各种活动.管理员.运营可以在平台后台管理系统中管理商品.订单.会员等.客服可以 ...

  3. python_面试题_TCP的三次握手与四次挥手问题

    1.相关问题 问题1: 请详细描述三次握手和四次挥手的过程,并画出状态图 问题2: 四次挥手中TIME_WAIT状态存在的目的是什么? 问题3: TCP是通过什么机制保障可靠性的? 2.问题回答 问题 ...

  4. Shell编程、part3

    本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...

  5. websocket服务器推送 (node+express+vue+socket)

    简介: 此项目需要懂一点node.express 功能: 1.前端用户登录,查看服务端推送的消息,用户只能在一个地方登录,也就是单点登录 2.服务端首先登录,上传需要推送的信息文本,后台读取文本后,存 ...

  6. ElasticSearch 7.3.0 查询、修改、删除 文档操作

    PUT chuyuan/_doc/ { "name":"xiaolin", , "sex":"F", "lov ...

  7. 极*Java速成教程 - (1)

    序言 众所周知,程序员需要快速学习新知识,所以就有了<21天精通C++>和<MySQL-从删库到跑路>这样的书籍,Java作为更"高级"的语言也不应该落后, ...

  8. Who will be punished

    Who will be punished Problem Description This time,suddenly,teacher Li wants to find out who have mi ...

  9. [题解][洛谷]_U75702/P5462_X龙珠_论何为字典序

    赛时嫌麻烦,没写 赛后自闭了,写了一下午 题目描述 “X龙珠”是一款益智小游戏.游戏中有 n(2|n)n(2∣n) 个编号互不相同龙珠按照给定的顺序排成一个队列,每个龙珠上面都有一个编号.每次操作时, ...

  10. docker无法删除<none>镜像

    .进入root权限 sudo su # 或 sudo -i .停止所有的container(这样才能够删除其中的images): docker stop $(docker ps -a -q) 如果想要 ...