【2016多校】T2 forest (树形DP,数论)

题意:有一棵N个点的树,每个点上有点权

定义路径长度为所经过的所有点的点权之和,树的直径为一棵树中最大的路径长度

有N次询问,每次询问要求回答所有树的直径之积

每次询问后会删一条边,树的数量会+1

要求回答N次询问,答案 mod 10^9+7

n<=100000

思路:因为知道每次删哪条边所以可以离线倒着做,每次加一条边

加边会使两棵树合并,考虑树的合并

已知原树的形状,可知点之间的父子关系

考虑DP,设dp[u,1],dp[u,2]为以U为根,子树中路径的最长与次长值,同时记录从哪个儿子取到

f[u]为以U为根的子树中的路径最大长度

注意最长与次长必须由两个不同的儿子转移来,更新时注意

对于ans[i]要合并X与Y,在原树中它们必定是父子关系

设X为Y的父亲

新的ANS就是旧的ans/旧的f[y]*新的f[合并后子树的根,即X的最上层根节点]

向上递归即可

出现除法取模,使用费马小定理求逆元

a^(p-2)=a^-1 (mod p)

题解方法是暴力+倍增优化,直径由U1,V1,U2,V2四个点对取最大值

然而我懒得写了

  1 const mo=1000000007;
  2 var g:array[1..100000,1..2]of int64;
  3     h:array[1..100000,1..2]of longint;
  4     fa,cx,cy,b,ff:array[1..100000]of longint;
  5     f,a,ans:array[1..100000]of int64;
  6     head,vet,next:array[1..300000]of longint;
  7     n,i,x,y,tot:longint;
  8     t:int64;
  9
 10 procedure add(a,b:longint);
 11 begin
 12  inc(tot);
 13  next[tot]:=head[a];
 14  vet[tot]:=b;
 15  head[a]:=tot;
 16 end;
 17
 18 function max(x,y:int64):int64;
 19 begin
 20  if x>y then exit(x);
 21  exit(y);
 22 end;
 23
 24 procedure swap(var x,y:longint);
 25 var t:longint;
 26 begin
 27  t:=x; x:=y; y:=t;
 28 end;
 29
 30 procedure dfs(u,pre:longint);
 31 var e,v:longint;
 32 begin
 33  e:=head[u];
 34  while e<>0 do
 35  begin
 36   v:=vet[e];
 37   if v<>pre then
 38   begin
 39    ff[v]:=u;
 40    dfs(v,u);
 41   end;
 42   e:=next[e];
 43  end;
 44 end;
 45
 46 function mi(x,y:int64):int64;
 47 var tmp:int64;
 48 begin
 49  mi:=1; tmp:=x;
 50  while y>0 do
 51  begin
 52   if y and 1=1 then mi:=mi*tmp mod mo;
 53   tmp:=tmp*tmp mod mo;
 54   y:=y>>1;
 55  end;
 56 end;
 57
 58 function exf(x:int64):int64;
 59 begin
 60  exit(mi(x,mo-2));
 61 end;
 62
 63 begin
 64  assign(input,‘forest.in‘); reset(input);
 65  assign(output,‘forest.out‘); rewrite(output);
 66  readln(n);
 67  for i:=1 to n do
 68  begin
 69   read(a[i]);
 70   f[i]:=a[i];
 71  end;
 72  for i:=1 to n-1 do
 73  begin
 74   read(cx[i],cy[i]);
 75   add(cx[i],cy[i]);
 76   add(cy[i],cx[i]);
 77  end;
 78  for i:=1 to n-1 do read(b[i]);
 79  dfs(1,-1);
 80  t:=1;
 81  for i:=1 to n do t:=t*a[i] mod mo;
 82  ans[n]:=t;
 83  for i:=n-1 downto 1 do
 84  begin
 85   x:=cx[b[i]]; y:=cy[b[i]];
 86   if ff[y]<>x then swap(x,y);
 87   t:=t*exf(f[y]) mod mo;
 88   fa[y]:=x;
 89   while x>0 do
 90   begin
 91    if fa[x]=0 then t:=t*exf(f[x]) mod mo;
 92    f[x]:=max(f[x],f[y]);
 93    if g[y,1]+a[y]>g[x,1] then
 94    begin
 95     if h[x,1]<>y then
 96     begin
 97      g[x,2]:=g[x,1]; h[x,2]:=h[x,1];
 98     end;
 99     g[x,1]:=g[y,1]+a[y];
100     h[x,1]:=y;
101    end
102     else if (g[y,1]+a[y]>g[x,2])and(y<>h[x,1]) then
103     begin
104      g[x,2]:=g[y,1]+a[y];
105      h[x,2]:=y;
106     end;
107    f[x]:=max(f[x],g[x,1]+g[x,2]+a[x]);
108    y:=x; x:=fa[x];
109   end;
110   t:=t*f[y] mod mo;
111   ans[i]:=t;
112  end;
113  for i:=1 to n do writeln(ans[i]);
114
115  close(input);
116  close(output);
117 end.
时间: 2024-10-23 11:46:17

【2016多校】T2 forest (树形DP,数论)的相关文章

hdu5293 Tree chain problem 树形dp+线段树

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最大. 比赛的时候以为是树链剖分就果断没去想,事实上是没思路. 看了题解,原来是树形dp.话说多校第一场树形dp还真多. . .. 维护d[i],表示以i为根节点的子树的最优答案. sum[i]表示i的儿子节点(仅仅能是儿子节点)的d值和. 那么答案就是d[root]. 怎样更新d值 d[i] = max(sum[i] , w[p]+s

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

2016 CCPC 网络赛 A - A water problem 水题,但读题有个坑,输入数字长度很大.. B - Zhu and 772002 题意:给出n个数(给出的每个数的质因子最大不超过2000),选出多个数相乘得b.问有多少种选法让b 为完全平方数. tags:高斯消元,求异或方程组解的个数.   好题 每个数先素数分解开.  对于2000以内的每个素数p[i],这n个数有奇数个p[i]则系数为1,偶数个则系数为0,最后n个数的p[i]系数异或和都要为0才会使得最后的积为完全平方数.

树形dp

树形dp,意思就是在树上的dp, 看了看紫书,讲了三个大点把,一个是树的最大独立集,另外一个是树的重心,最后一个是树的最长路径.给的三个例题,下面就从例题说起 第一个:工人的请愿书 uva 12186 这个题目给定一个公司的树状结构,每个员工都有唯一的一个直属上司,老板编号为0,员工1-n,只有下一级的工人请愿书不小于T%时,这个中级员工,才会签字传递给它的直属上司,问老板收到请愿书至少需要多少各个工人签字 用dp(u)表示u给上级发信至少需要多少工人,那么可以假设u有k个节点,所以需要c =

POJ 1655 Balancing Act[树的重心/树形dp]

Balancing Act 时限:1000ms Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree

NOIP2011pj表达式的值[树形DP 笛卡尔树]

题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算. 现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 . 输入输出格式 输入格式: 输入文件名为exp.in ,共 2 行. 第1 行为一个整数 L,表示给定的表达式中除去横线外的运

HDU1520(树形dp)

H - Anniversary party Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical

青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理.(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离

多叉树转二叉树+树形dp(codevs 1746 贪吃的九头龙 2002noi)

题目传送门 看到这个题目我们要先把问题简化了,条件中是多叉树,我们可以把它转换成二叉树,左边是儿子右边是兄弟的储存方式. 首先先判断否的部分,当总的果子小于需求,也就是N-k<M-1时输出-1. 我们再判断是的部分 如果没有大头,一定存在难受值为0的方案但是现在题目中有大头,我们就可以按按照小头的个数进行分类 1.有一个小头,我们要考虑小头和大头的难受值之和. 2.有多个小头,因为小头可以在奇偶的进行变换,所以我们只需要考虑大头的难受值. 分析到这里,我们就可以发现是树形dp我们设f[i][j]

csu 2014 summer day 4 树形dp升阶

POJ 1155 题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号. 要知道用户都在叶子节点,费用消耗在使用选择的路径上,每条路径的使用费用给出,每个用户支付的费用给出. 输入:N为总节点数,M为用户数,1为电视台, 2 to N-M 是中转站,N-M+1到N是潜在用户 对于1到N-M的中继点,给出连接的点的个数K,K对(A,C)表示连接到A点,这条路径的费用是C 最后是M个整数,表示用户支付的费用 分析: int

算法提高 金属采集_树形dp

算法提高 金属采集 时间限制:1.0s   内存限制:256.0MB 问题描述 人类在火星上发现了一种新的金属!这些金属分布在一些奇怪的地方,不妨叫它节点好了.一些节点之间有道路相连,所有的节点和道路形成了一棵树.一共有 n 个节点,这些节点被编号为 1~n .人类将 k 个机器人送上了火星,目的是采集这些金属.这些机器人都被送到了一个指定的着落点, S 号节点.每个机器人在着落之后,必须沿着道路行走.当机器人到达一个节点时,它会采集这个节点蕴藏的所有金属矿.当机器人完成自己的任务之后,可以从任