树pao(雾)
今天难得睡醒了,大概睡了13个小时,打算今晚把树剖学了。
嘿嘿嘿雀魂真好玩,这篇文章咕了
有学上了,找到了水平远高于我的队友,好开心的说,,,
卡空间感觉治不了了。。。
板子题是洛谷P3384
实在不知道怎么优化了,感觉应该是哪里写错了,但是是MLE又不是WA,明天再说惹
参考博客:
https://www.cnblogs.com/pks-t/p/9194322.html#_label0
https://www.cnblogs.com/George1994/p/7821357.html
下面那篇要好懂一些,码风也不错。所以为什么还要粘上面的呢?
其实树剖真不难。。就是码量大一些,如果你会 线段树,dfs序,lca。那么应该一看就懂了。
树剖其实就是把一个树剖成很多条链,然后在链上搞来搞去。
先来了解一下概念
- 重结点:子树结点数目最多的结点;
- 轻节点:父亲节点中除了重结点以外的结点;
- 重边:父亲结点和重结点连成的边;
- 轻边:父亲节点和轻节点连成的边;
- 重链:由多条重边连接而成的路径;
- 轻链:由多条轻边连接而成的路径;

然后有几个结论,不会证真的不会证,········· 记不得了,可以看上面blog
反正就是告诉你我们这样搞不会t。。。
那么我们怎么维护呢
比方说我们要 求 x 到 y 的路径长。
当x与y不在一条重链上时,我们可以 往上跳,跳到 top[x]这个位置,然后累加这一段答案,因为x与top[x]在一条重链所以很简单。
这样跳呀跳呀就跳到一条重链上去了。 然后再算一下就阔以了。
为什么不会T呢?复杂度是什么呢?这些我都不会。
同理 更新操作也是一样的。
如果对子树呢? 显然子树内的序号都是连续的。所以直接对 tid[x],tid[x]+siz[x]-1 这段区间搞来搞去就行了。
484很简单qwq
嗯敲代码的时候可就爽死你了
哦还没有说怎么算top,hson这些东西,可以先dfs一下求siz和hson。再dfs一下求top。具体看代码。
然后粘一个适合我自己码风的板子。vector的改天再说。因为自己平时喜欢vector。。。
要板子的话可以去看上面blog,真的讲得很好,每一步的代码什么的。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read() {
int X=,w=; char c=getchar();
while (c<''||c>'') { if (c=='-') w=-; c=getchar(); }
while (c>=''&&c<='') X=(X<<)+(X<<)+c-'',c=getchar();
return X*w;
}
const int N = 1e5+;
struct Edge{
int to,next;
}edge[N];int cnt=;int head[N];
void addEdge(int u,int v){
edge[++cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
}
struct Node{
int lz,val;
}tree[N];
int siz[N],top[N],hson[N],dep[N],fa[N],tid[N],ran[N];
int n,m,r,p,val[N],tot=;
void dfs1(int u,int par,int d){
dep[u]=d;
fa[u]=par;
siz[u]=;
for(int i=head[u];i;i=edge[i].next){
int v = edge[i].to;
if(v!=fa[u]){
dfs1(v,u,d+);
siz[u]+=siz[v];
if(hson[u]==-||siz[v]>siz[hson[u]]){
hson[u]=v;
}
}
}
}
void dfs2(int u,int t){
top[u]=t;
tid[u]=++tot;
ran[tot]=u;
if(!hson[u])return;
dfs2(hson[u],t);
for(int i=head[u];i;i=edge[i].next){
int v = edge[i].to;
if(v!=hson[u]&&v!=fa[u]){
dfs2(v,v);
}
}
}
void push_up(int x){
tree[x].val=(0ll+tree[x<<].val+tree[x<<|].val)%p;
}
void push_down(int x,int l,int r){
if(!tree[x].lz)return;
int mid=l+r>>;
tree[x<<].val=(0ll+tree[x<<].val+(mid-l+)*tree[x].lz)%p;
tree[x<<|].val=(0ll+tree[x<<|].val+(r-mid)*tree[x].lz)%p;
tree[x<<].lz=(0ll+tree[x<<].lz+tree[x].lz)%p;
tree[x<<|].lz=(0ll+tree[x<<|].lz+tree[x].lz)%p;
tree[x].lz=;
}
void build(int k,int l,int r){
if(l==r){
tree[k].val=val[ran[l]]%p;
} else{
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
push_up(k);
}
}
int query(int l,int r,int ql,int qr,int rt){
int res = ;
if(ql<=l&&qr>=r){
res=(0ll+res+tree[rt].val)%p;
return res;
}
int mid = (l+r)>>;
push_down(rt,l,r);
if(ql<=mid) res=(0ll+res+query(l,mid,ql,qr,rt<<))%p;
if(qr>mid) res=(0ll+res+query(mid+,r,ql,qr,rt<<|))%p;
return res;
}
void upd(int l,int r,int ul,int ur,int rt,int k){
if(ul<=l&&ur>=r) {
tree[rt].val = (tree[rt].val + k * (r - l + ))%p;
tree[rt].lz+=k;
return;
}
int mid=l+r>>;
push_down(rt,l,r);
if(ul<=mid)upd(l,mid,ul,ur,rt<<,k);
if(ur>mid)upd(mid+,r,ul,ur,rt<<|,k);
push_up(rt);
}
int query_p(int u,int v){//x
int ans=;
while (top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=(0ll+ans%p+query(,n,tid[top[u]],tid[u],))%p;
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans=(0ll+ans+query(,n,tid[u],tid[v],))%p;
return ans;
}
void upd_p(int u,int v,int z){
z%=p;
while (top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
upd(,n,tid[top[u]],tid[u],,z);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
upd(,n,tid[u],tid[v],,z);
}
int main(){
n=read();m=read();r=read();p=read();
for(int i=;i<=n;i++)val[i]=read();
int op,x,y,z;
for(int i=;i<n;i++){
x=read();y=read();
addEdge(x,y);
addEdge(y,x);
}
dfs1(r,,);
dfs2(r,r);
build(,,n);
/**while (m--){
op=read();
if(op==1){
x=read();y=read();z=read();
upd_p(x,y,z);
} else if(op==2){
x=read();y=read();
printf("%d\n",query_p(x,y));
} else if(op==3){
x=read();z=read();
upd(1,n,tid[x],tid[x]+siz[x]-1,1,z);
} else{
x=read();
printf("%d\n",query(1,n,tid[x],tid[x]+siz[x]-1,1));
}
}*/
}
树pao(雾)的更多相关文章
- P1314 聪明的质监员 二分答案
这个题我第一反应是线段树(雾),然后看了一眼题解之后就后悔了...前缀和...然后二分答案,然后就没有然后了. 题干: 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 nnn 个矿石 ...
- atcoder 泛做
https://atcoder.jp/contests/arc060/tasks/arc060_b 先考虑一些特殊情况: $$n>s$$ $$n=s$$ $b$小于$sqrt(N)$可以枚举,如 ...
- inline void 树状数组神奇感悟【雾
才发现扫描线可以用树状数组搞... 致远星患者 (另外根据这篇博文的内容怎么越来越感觉自己往 PJ 入门靠拢了...) 还有一点,咱把树状数组当做线段树来康的话其实一切都会很清晰,这个来张四合一的图: ...
- BZOJ 3524主席树裸题 (雾)
思路: 按权值建一棵主席树 (但是这好像不是正解 空间复杂度是不对的--.) //By SiriusRen #include <cstdio> #include <cstring&g ...
- 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)
最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- 线段树初步&&lazy标记
线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...
- hdu 5269 trie树
现场想到了lowbit(X xor Y)=X和Y从右向左数,对应相同的数的个数+1...然而并没有想到接下来用trie树 然后就想排个序试试...然后就整个人都不好了啊摔 sol:用trie,一边in ...
- paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他
在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...
随机推荐
- JSON序列——保存修改数据2
JSON序列——保存修改数据2 procedure TForm1.Button7Click(Sender: TObject); begin var delta: TynJsonDelta := Tyn ...
- Pipenv和Python虚拟环境
Pipenv & 虚拟环境 本教程将引导您完成安装和使用 Python 包. 它将向您展示如何安装和使用必要的工具,并就最佳做法做出强烈推荐.请记住, Python 用于许多不同的目的.准确地 ...
- wordclock中文模式快一个小时怎么调整
wordclock屏幕保护,设置为中文模式,显示的时间比系统时间要快一个小时,其实软件自带的配置文件可以设置调整到正常时间…… 工具/原料 wordclock 方法/步骤 桌面上右键菜 ...
- 如何确定Isilon cluster的网卡类型是40GbE的还是10GbE的
可以使用isi upgrade cluster firmware devices命令. 从命令行输出可以看到,当前的cluster使用的是40G的前端网卡. 如果是10G网卡,输出结果应当是如下的样子 ...
- jquery 多级联动下拉列表含(数据模型)
方法 /** * 级联 * 联动 * @param url:访问json数据的地址 * @param param:参数 * @param levelIds:页面下拉标签数组,为联动级数 * @priv ...
- 转: 关于linux用户时间与系统时间的说明
写的很不错的一篇. https://blog.csdn.net/mmshixing/article/details/51307853
- idea 集成sonarLint检查代码bugs
1.目标 idea集成sonar的代码检查,实现可以在提交代码前就检查你的代码,而不是将代码提交之后,之后再去检查. Sonar可以从以下七个维度检测代码质量,而作为开发人员至少需要处理前5种代码质量 ...
- Xtrabackup简介
Xtrabackup是由 Percona 开发的一个开源软件,可实现对 InnoDB 的数据备份,支持在线热备份(备份时不影响数据读写),特点如下: 备份过程快速.可靠: 备份过程不会打断正在执行的事 ...
- numpy累积
numpy累积有两类函数:np.cumxxxxx和np.ufunc.accumulate() import numpy as np a = np.arange(1, 5) print(np.cumpr ...
- 减少网站跳转时间,增强网站数据安全——HSTS 详解
近年来随着 Google.Apple.百度等公司不断推动 HTTPS 普及,全网 HTTPS 已是大势所趋.目前多数网站都已经支持 HTTPS 访问,但是在由 HTTP 转向 HTTPS 路程中,不少 ...