树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最佳论文.作者 ...
随机推荐
- django之模型层(model)--添加、单表查询、修改基础
上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...
- set non-stop on
# Enable the async interface. set target-async 1 # If using the CLI, pagination breaks non-stop. set ...
- 【总结】瞬时高并发(秒杀/活动)Redis方案
1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据 一个字符串类型的值最多能存储512M字节的内容 利用INCR命令簇(IN ...
- DevSecOps 运维模式中的安全性
本文想从技术的角度谈谈我对云计算数据中心 DevSecOps 运维模式中的安全性的理解,和过去几年我在云服务业务连续性管理方面的探索. 现在公有云服务商都不约而同地转向 DevSecOps 模式.De ...
- 通过Nginx反向代理之后客户端验证码session不一致造成无法验证通过的问题解决
location / { proxy_pass http://127.0.0.1:9080/app/; proxy_cookie_path /app/ /; proxy_cookie_path /ap ...
- BABLE 原理
1.babel转换原理 2.主要过程 (1)babylon进行解析得到AST (2)babel-traverse插件对AST树进行遍历转译得到新的AST树 (3)babel-generator将AST ...
- 如何将自己写的verilog模块封装成IP核
如何将自己写的verilog模块封装成IP核 (2014-11-21 14:53:29) 转载▼ 标签: 财经 分类: 我的东东 =======================第一篇========= ...
- [svc]证书学习索引
数字证书基础知识 对称加密/非对称加密细枝末节 openssl对称非对称加密实战 使用OpenSSL实现CA证书的搭建过程 通过openssl生成证书 HTTPS证书生成原理和部署细节 证书各个字段的 ...
- [k8s]Docker 用户使用 kubectl 命令指南-unkown排错(kubelet端口解析)
参考:https://kubernetes.io/docs/user-guide/kubectl-cheatsheet/ https://k8smeetup.github.io/docs/user-g ...
- 使用DotfuscatorPro_4.9对软件dll库进行加密
点击settings选项,Disable String Encryption改成NO,具体里面的设置如下图. 再点击Rename选项下的options,左边的选项勾上,再把Renaming Schem ...