[xsy2123]毛毛虫
题意:有一棵带点权的树,链修改是把$(x,y)$这条链和与其相邻的节点都加上一个数,查询是问$(x,y)$这条链和与其相邻的节点的权值和
学到了一个新姿势?
考虑树链剖分,在剖重链时每次给当前节点的儿子顺次标号,那么一条重链上所有节点的儿子的标号是连续的,也就对应着题目的限制,再补上漏掉的$lca_{x,y}$和$fa_{lca_{x,y}}$即可
#include<stdio.h> typedef long long ll; void swap(int&a,int&b){a^=b^=a^=b;} int h[100010],nex[200010],to[200010],v[100010],M; void add(int a,int b){ M++; to[M]=b; nex[M]=h[a]; h[a]=M; } int siz[100010],dep[100010],fa[100010],son[100010],n; void dfs(int x){ int i,k=0; siz[x]=1; dep[x]=dep[fa[x]]+1; for(i=h[x];i;i=nex[i]){ if(to[i]!=fa[x]){ fa[to[i]]=x; dfs(to[i]); siz[x]+=siz[to[i]]; if(siz[to[i]]>siz[k])k=to[i]; } } son[x]=k; } int bl[100010],p[100010],pos[100010],L[100010],R[100010]; void dfs(int x,int chain){ int i; bl[x]=chain; L[x]=M+1; for(i=h[x];i;i=nex[i]){ if(to[i]!=fa[x]){ p[++M]=to[i]; pos[to[i]]=M; } } R[x]=M; if(son[x])dfs(son[x],chain); for(i=h[x];i;i=nex[i]){ if(to[i]!=fa[x]&&to[i]!=son[x])dfs(to[i],to[i]); } } ll s[400010],d[400010]; void pushup(int x){s[x]=s[x<<1]+s[x<<1|1];} void build(int l,int r,int x){ if(l==r){ s[x]=v[p[l]]; return; } int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); pushup(x); } void ad(int x,int len,ll v){ d[x]+=v; s[x]+=len*v; } void pushdown(int x,int ln,int rn){ if(d[x]){ ad(x<<1,ln,d[x]); ad(x<<1|1,rn,d[x]); d[x]=0; } } void modify(int L,int R,int v,int l,int r,int x){ if(L>R)return; if(L<=l&&r<=R)return ad(x,r-l+1,v); int mid=(l+r)>>1; pushdown(x,mid-l+1,r-mid); if(L<=mid)modify(L,R,v,l,mid,x<<1); if(mid<R)modify(L,R,v,mid+1,r,x<<1|1); pushup(x); } ll query(int L,int R,int l,int r,int x){ if(L>R)return 0; if(L<=l&&r<=R)return s[x]; int mid=(l+r)>>1; ll s=0; pushdown(x,mid-l+1,r-mid); if(L<=mid)s+=query(L,R,l,mid,x<<1); if(mid<R)s+=query(L,R,mid+1,r,x<<1|1); return s; } int lca(int x,int y){ while(bl[x]!=bl[y]){ if(dep[bl[x]]<dep[bl[y]])swap(x,y); x=fa[bl[x]]; } return dep[x]<dep[y]?x:y; } void modify(int x,int y,int v){ int u=lca(x,y); while(bl[x]!=bl[u]){ modify(L[bl[x]],R[x],v,1,n,1); x=fa[bl[x]]; } while(bl[y]!=bl[u]){ modify(L[bl[y]],R[y],v,1,n,1); y=fa[bl[y]]; } if(dep[x]>dep[y])swap(x,y); modify(L[x],R[y],v,1,n,1); modify(pos[x],pos[x],v,1,n,1); if(fa[x])modify(pos[fa[x]],pos[fa[x]],v,1,n,1); } ll query(int x,int y){ int u=lca(x,y); ll s=0; while(bl[x]!=bl[u]){ s+=query(L[bl[x]],R[x],1,n,1); x=fa[bl[x]]; } while(bl[y]!=bl[u]){ s+=query(L[bl[y]],R[y],1,n,1); y=fa[bl[y]]; } if(dep[x]>dep[y])swap(x,y); s+=query(L[x],R[y],1,n,1)+query(pos[x],pos[x],1,n,1); if(fa[x])s+=query(pos[fa[x]],pos[fa[x]],1,n,1); return s; } int main(){ int m,i,x,y,z; scanf("%d",&n); for(i=1;i<n;i++){ scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(i=1;i<=n;i++)scanf("%d",v+i); dfs(1); M=1; p[1]=1; pos[1]=1; dfs(1,1); build(1,n,1); scanf("%d",&m); while(m--){ scanf("%d%d%d",&i,&x,&y); if(i==1){ scanf("%d",&z); modify(x,y,z); }else printf("%lld\n",query(x,y)); } }
[xsy2123]毛毛虫的更多相关文章
- 【HAOI2009】【P1307】毛毛虫
感觉相比其他树归题简单多了,不过有点绕(也许是我的思路很奇怪一.一)(这是省选题啊,就算作为T1这题也太水了,HA好弱……) 原题: 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一 ...
- [haoi2009]毛毛虫 树形dp
这道题细节处理不少,但要AC不难: 设以i节点为根节点的子树能形成的最大的毛毛虫长度为f[i],则f[i]=max(f[j])+i节点的孩子数: 答案需要f最大和次大的两个子树合并,而且若合并的位置不 ...
- [HAOI2009]毛毛虫
题目描述 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大.例如下图左边的树(图 1 )抽出一部分就变成了右边的一个毛毛虫了(图 2 ). 输入输出格 ...
- 【HAOI2009】毛毛虫
题面 题目描述 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大.例如下图左边的树(图 1 )抽出一部分就变成了右边的一个毛毛虫了(图 2 ). 输入 ...
- 【luogu3174】【HAOI2009】毛毛虫
Description 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大. Input 在文本文件 worm.in 中第一行两个整数 N , M ,分 ...
- P3174 [HAOI2009]毛毛虫
题目描述 对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大.例如下图左边的树(图 1 )抽出一部分就变成了右边的一个毛毛虫了(图 2 ). 输入输出格 ...
- loj #6570. 毛毛虫计数
$ \color{#0066ff}{ 题目描述 }$ hsezoi 巨佬 olinr 喜欢 van 毛毛虫,他定义毛毛虫是一棵树,满足树上存在一条树链,使得树上所有点到这条树链的距离最多为 1. 给定 ...
- loj6570 毛毛虫计数(生成函数FFT)
link 巨佬olinr的题解 <-- olinr很强 考虑生成函数 考虑直径上点数>=4的毛毛虫的直径,考虑直径中间那些节点以及他上面挂的那些点的EGF \(A(x)=\sum_{i\g ...
- [洛谷P3174][HAOI2009]毛毛虫
题目大意:给一棵树,求其中最大的“毛毛虫”,毛毛虫的定义是一条链上分出几条边 题解:把每个点的权值定义为它的度数减一,跑带权直径即可,最后答案加二 卡点:无 C++ Code: #include &l ...
随机推荐
- java 连接数据库报错:Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '
1.解决方法: 报错信息为: Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server ti ...
- 父元素与子元素之间的margin-top问题(css hack)
hack: 父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. hytml代码: &l ...
- VMware12序列号
VMware tools怎么删除 rpm -e open-vm-tools-desktop vm12序列号 5A02H-AU243-TZJ49-GTC7K-3C61NVF5XA-FNDDJ-085GZ ...
- linux下暴力破解工具hydra【转】
一.简介 Number one of the biggest security holes are passwords, as every password security study shows. ...
- Python大牛开小灶,一对一问答
CSDN知识小饭桌 大牛开小灶 小范围,高质量,在线交流QA 参与嘉宾 知识库特邀编辑伊海波,滴滴出行工程师,曾任龙图龙图游戏数据分析部技术负责人.CSDN博客专家,资深Python/Golang ...
- 【uva11248】网络扩容
网络流裸题. 求完最大流之后保留残余容量信息,依次将已经加入最小割的弧变成c再跑,记录下即可. #include<bits/stdc++.h> #define N 20005 #defin ...
- C基础 算法实现层面套路
引言 - 从实践狗讲起 理论到实践(有了算法到实现) 中间有很多过程. 算法方面本人啥也不懂, 只能说说实现方面. 例如下面 一个普通的插入排序. // // 插入排序默认从大到小 // extern ...
- python按比例随机切分数据
在机器学习或者深度学习中,我们常常碰到一个问题是数据集的切分.比如在一个比赛中,举办方给我们的只是一个带标注的训练集和不带标注的测试集.其中训练集是用于训练,而测试集用于已训练模型上跑出一个结果,然后 ...
- Centos7 配置网络
/* Centos7 的网络 不可以用ifconfig获取,需要安装包 所以 .*/ //查看ip [root@master ~]# ip a /* Centos7 的网卡名字与 Centos6有区别 ...
- vue的data用到this问题
问题:在vue中用vue-awesome-swiper,在data中初始化,用到swiper一个方法onTap,然后再调vue的一个函数,用到this,可是... data() { return { ...