2018牛客网暑假ACM多校训练赛(第二场)E tree 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round2-E.html
题目传送门 - 2018牛客多校赛第二场 E
题意
一棵 $n$ 个结点的树,每个点有一个点权,有 $m$ 次操作,每次操作有三种:
1. 修改一个点的点权
2. 修改一个点的父亲
3. 询问包含某个点的所有大小为 $c$ 的连通块的点权乘积之和。
$n,m\leq 100000,c\leq10 $
题解
以上题解图片摘自 laofu 题解。
我再画几幅图介绍一下:
注:箭头表示箭头尾端节点的 dp 对箭头指向节点有 dp 贡献。
虚箭头表示中间省略一些有箭头连接的节点。
虚线表示中线省略一些节点,但是没有箭头连接。
每个图,最上面的节点表示往上走 $10$ 步到达的祖先。
最下面的节点表示操作中的 $x$ 节点。
注意一下修改和询问里面各有一个特殊箭头,意义自己理解。
代码
#include <bits/stdc++.h>
using namespace std;
int read(){
char ch=getchar();
int x=0;
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
const int N=100005,mod=1e9+7;
int n,m,val[N],fa[N];
int dp[N][11];
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=1LL*x*x%mod)
if (y&1)
ans=1LL*ans*x%mod;
return ans;
}
void DP(int a,int b){
if (!a||!b)
return;
for (int i=10;i>=1;i--)
for (int j=1;j<i;j++)
dp[a][i]=(1LL*dp[a][i]+1LL*dp[a][j]*dp[b][i-j])%mod;
}
void IDP(int a,int b){
if (!a||!b)
return;
for (int i=1;i<=10;i++)
for (int j=1;j<i;j++)
dp[a][i]=(1LL*dp[a][i]-1LL*dp[a][j]*dp[b][i-j])%mod;
}
int main(){
n=read(),m=read();
memset(dp,0,sizeof dp);
for (int i=1;i<=n;i++)
dp[i][1]=val[i]=read();
for (int i=2;i<=n;i++)
fa[i]=read();
for (int i=n;i>1;i--)
DP(fa[i],i);
while (m--){
int opt=read(),x=read(),y=read(),anc[15];
if (opt==0){
for (int i=1,j=x;i<=10;i++,j=fa[j])
anc[i]=j;
for (int i=10;i>1;i--)
IDP(anc[i],anc[i-1]);
int inv=Pow(val[x],mod-2);
val[x]=y;
for (int i=1;i<=10;i++)
dp[x][i]=1LL*dp[x][i]*inv%mod*y%mod;
for (int i=1;i<10;i++)
DP(anc[i+1],anc[i]);
}
if (opt==1){
for (int i=1,j=x;i<=10;i++,j=fa[j])
anc[i]=j;
for (int i=10;i>1;i--)
IDP(anc[i],anc[i-1]);
for (int i=2;i<10;i++)
DP(anc[i+1],anc[i]);
fa[x]=y;
for (int i=1,j=x;i<=10;i++,j=fa[j])
anc[i]=j;
for (int i=10;i>2;i--)
IDP(anc[i],anc[i-1]);
for (int i=1;i<10;i++)
DP(anc[i+1],anc[i]);
}
if (opt==2){
for (int i=1,j=x;i<=10;i++,j=fa[j])
anc[i]=j;
for (int i=10;i>1;i--)
IDP(anc[i],anc[i-1]);
for (int i=10;i>1;i--)
DP(anc[i-1],anc[i]);
printf("%d\n",(dp[x][y]+mod)%mod);
for (int i=1;i<10;i++)
IDP(anc[i],anc[i+1]);
for (int i=1;i<10;i++)
DP(anc[i+1],anc[i]);
}
}
return 0;
}
2018牛客网暑假ACM多校训练赛(第二场)E tree 动态规划的更多相关文章
- 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html 题目传送门 - 2018牛客多校赛第三场 I ...
- 2018牛客网暑假ACM多校训练赛(第三场)G Coloring Tree 计数,bfs
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html 题目传送门 - 2018牛客多校赛第三场 G ...
- 2018牛客网暑假ACM多校训练赛(第三场)D Encrypted String Matching 多项式 FFT
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-D.html 题目传送门 - 2018牛客多校赛第三场 D ...
- 2018牛客网暑假ACM多校训练赛(第十场)H Rikka with Ants 类欧几里德算法
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-H.html 题目传送门 - https://www.n ...
- 2018牛客网暑假ACM多校训练赛(第十场)F Rikka with Line Graph 最短路 Floyd
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-F.html 题目传送门 - https://www.n ...
- 2018牛客网暑假ACM多校训练赛(第十场)D Rikka with Prefix Sum 组合数学
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-D.html 题目传送门 - https://www.n ...
- 2018牛客网暑假ACM多校训练赛(第八场)H Playing games 博弈 FWT
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round8-H.html 题目传送门 - https://www.no ...
- 2018牛客网暑假ACM多校训练赛(第七场)I Tree Subset Diameter 动态规划 长链剖分 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round7-I.html 题目传送门 - https://www.n ...
- 2018牛客网暑假ACM多校训练赛(第六场)I Team Rocket 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round6-I.html 题目传送门 - https://www.no ...
随机推荐
- Light OJ 1007
求区间欧拉函数平方和... 最后因为longlong 范围爆了WA 了, 0.0 #include<bits/stdc++.h> using namespace std; const in ...
- CURL错误代码及含义
https://curl.haxx.se/libcurl/c/libcurl-errors.html NAME libcurl-errors - error codes in libcurl DESC ...
- 解决layui选中项下一页清空问题
项目中遇到给用户在所有产品中匹配一部分产品.用layui 第一页选好之后到第二页再选,等回到第一页时之前选择的都没了,解决这个问题的办法如下: //勾选的产品id集合 var chooseAdids ...
- jqgrid获取数据条数
function getResult() {//获取结果结合的函数,可以通过此函数获取查询后匹配的所有数据行. var o = jQuery("#jqgrid"); ...
- jq获取页面url后边带的参数
//获取url后边的参数 $.getUrlParam = function (name) { var reg = new RegExp("(^|&) ...
- Confluence 6 log4j 日志级别
日志级别 DEBUG - 被设计为用来获得最多的信息和事件,在对应用程序进行调试的时候,这个日志级别通常能够提供最多的有效信息(查看应用程序怎么了) INFO - 有关系统正常运行-计划任务运行,服务 ...
- Confluence 6 使用 JConsole 监控本地 Confluence
如果你遇到了一些特定的问题,或者你仅仅是希望在一个很短的时间内监控你 Confluence 的运行,你可以使用本地监控.本地监控将会对你的服务器性能产生影响,所以我们并不推荐你使用本地监控来长时间的监 ...
- js之DOM对象三
一.JS中for循环遍历测试 for循环遍历有两种 第一种:是有条件的那种,例如 for(var i = 0;i<ele.length;i++){} 第二种:for (var i in ...
- 1705: 小明在工作(zzuli)
题目描述 小明的工作是负责记录饭堂中正在排队的人的信息 在他的工作中会有三种可能的事件发生: 1.编号为id的学生加入到队伍的最后面 2.排在最前面的学生打完饭离开了队伍 3. ...
- JMeter 提供了六种定时器
JMeter提供了六种定时器,下面让我们一起来学习下JMeter的定时器. 先明确一些概念: 1)定时器是在每个sampler(采样器)之前执行的,而不是之后: 是的,你没有看错,不管这个定时器的位置 ...