bzoj3083 遥远的国度 && bzoj3626 LCA (树链剖分)
今早刷了两道树剖的题目,用时两小时十五分钟= =
树剖的题目代码量普遍120+
其实打熟练之后是很容易调的,不熟练的话代码量大可能会因为某些小细节调很久
3083:裸树剖+“换根”
所谓换根其实只要判断一下当前询问点的子树和当前根的位置关系就好了,不能真的换根
根不在当前点的子树中则不影响;根在当前子树中,那么根所在的那部分子树不询问就可以了,而其他点都要询问
3626:这个题目很巧妙
有两个地方是很神的,一是将询问l~r转化为询问z一个点,二是离线操作O(qlog2n)就解决了询问
//bzoj3083
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 1000000010
using namespace std;
;
struct node{
int l,r,lz,mn;
}t[maxn*];
struct edge{
int to,next;
}e[maxn*];
,v0[maxn],opt;
void insert(int u, int v){
e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
}
void dfs1(int u, int f, int d){
size[u]=; fa[u]=f; dep[u]=d;
; i=e[i].next){
int v=e[i].to; if (v==f) continue;
dfs1(v,u,d+);
size[u]+=size[v];
if (!son[u] || size[v]>size[son[u]]) son[u]=v;
}
}
void dfs2(int u, int num){
top[u]=num; tree[u]=++cnt; pre[cnt]=u;
if (!son[u]) return;
dfs2(son[u],num);
; i=e[i].next)
if (e[i].to!=fa[u] && e[i].to!=son[u]) dfs2(e[i].to,e[i].to);
}
void pushup(int x){
t[x].mn=min(t[x<<].mn,t[x<<|].mn);
}
void pushdown(int x){
if (t[x].lz){
t[x<<].lz=t[x<<|].lz=t[x].lz;
t[x<<].mn=t[x<<|].mn=t[x].mn;
t[x].lz=;
}
}
void update(int a, int b, int w, int x){
int l=t[x].l, r=t[x].r;
if (l==a && r==b){
t[x].lz=;
t[x].mn=w;
return;
}
;
pushdown(x);
|);
);
),update(mid+,b,w,x<<|);
pushup(x);
}
int get_min(int a, int b, int x){
int l=t[x].l, r=t[x].r;
if (l==a && b==r) return t[x].mn;
;
pushdown(x);
);
|);
),get_min(mid+,b,x<<|));
}
void build(int l, int r, int x){
t[x].l=l, t[x].r=r;
if (l==r){
t[x].mn=v0[pre[l]];
t[x].lz=;
return;
}
;
);
,r,x<<|);
pushup(x);
}
void change(int x, int y, int c){
while (top[x]!=top[y]){
if (dep[x]<dep[y]) swap(x,y);
update(tree[top[x]],tree[x],c,);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
update(tree[x],tree[y],c,);
}
int main(){
scanf(; memset(head,-,;
; i<n; i++) scanf("%d%d", &u, &v),insert(u,v),insert(v,u);
dfs1(,,);
dfs2(,);
; i<=n; i++) scanf("%d", &v0[i]);
build(,cnt,);
scanf("%d", &cap);
while (Q--){
scanf("%d", &opt);
) scanf("%d", &cap);
){
scanf("%d%d%d", &u, &v, &w);
change(u,v,w);
}
){
scanf("%d", &u);
].mn);
else{
;
; i=e[i].next){
int v=e[i].to;
if (v==fa[u]) continue;
) child=v;
}
if (child){
,tree[child]-,));
int right=INF;
));
printf()));
}
,));
}
}
}
;
}
//bzoj3626
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MOD 201314
using namespace std;
;
struct node{
int l,r,lz,sum,len;
}t[maxn*];
struct edge{
int to,next;
}e[maxn*];
struct Ans{
int z,R,L;
}ans[maxn];
struct cover{
int p,id;
bool flag;
}a[maxn*];
int fa[maxn],dep[maxn],size[maxn],top[maxn],son[maxn],head[maxn],tot,cnt;
int tree[maxn],pre[maxn],n,q,u,v;
bool cmp(cover a, cover b){
return a.p<b.p;
}
void insert(int u, int v){
e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
}
void dfs1(int u, int f, int d){
fa[u]=f; dep[u]=d; size[u]=;
; i=e[i].next){
int v=e[i].to; if (v==f) continue;
dfs1(v,u,d+);
size[u]+=size[v];
if (!son[u] || size[v]>size[son[u]]) son[u]=v;
}
}
void dfs2(int u, int num){
top[u]=num; tree[u]=++cnt; pre[cnt]=u;
if (!son[u]) return;
dfs2(son[u],num);
; i=e[i].next)
if (e[i].to!=son[u] && e[i].to!=fa[u]) dfs2(e[i].to,e[i].to);
}
void pushup(int x){
t[x].sum=t[x<<].sum+t[x<<|].sum;
}
void pushdown(int x){
if (t[x].lz){
t[x<<].lz+=t[x].lz;
t[x<<|].lz+=t[x].lz;
t[x<<].sum+=t[x<<].len*t[x].lz;
t[x<<|].sum+=t[x<<|].len*t[x].lz;
t[x].lz=;
}
}
int query(int a, int b, int x){
int l=t[x].l, r=t[x].r;
if (l==a && r==b) return t[x].sum;
;
pushdown(x);
);
|);
)+query(mid+,b,x<<|);
}
void update(int a, int b, int x){
int l=t[x].l, r=t[x].r;
if (l==a && r==b){
t[x].sum+=t[x].len;
t[x].lz++;
return;
}
;
pushdown(x);
);
|);
),update(mid+,b,x<<|);
pushup(x);
}
void build(int l, int r, int x){
t[x].l=l, t[x].r=r; t[x].len=r-l+;
if (l==r){
t[x].sum=;
t[x].lz=;
return;
}
;
);
,r,x<<|);
pushup(x);
}
void tree_update(int x, int y){
while (top[x]!=top[y]){
if (dep[x]<dep[y]) swap(x,y);
update(tree[top[x]],tree[x],);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
update(tree[x],tree[y],);
}
int tree_query(int x, int y){
;
while (top[x]!=top[y]){
if (dep[x]<dep[y]) swap(x,y);
ret+=query(tree[top[x]],tree[x],); ret%=MOD;
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
) % MOD +ret) % MOD;
}
int main(){
scanf("%d%d", &n, &q);
tot=; memset(head,-,sizeof(head));
; i<n; i++){
scanf("%d", &u);
insert(u,i);
}
cnt=;
dfs1(,,);
dfs2(,);
build(,n,);
cnt=;
; i<=q; i++){
scanf("%d%d%d", &u, &v, &ans[i].z);
a[++cnt].p=u-; a[cnt].id=i; a[cnt].flag=;
a[++cnt].p=v; a[cnt].id=i; a[cnt].flag=;
}
sort(a+,a++cnt,cmp);
;
; i<=cnt; i++){
while (now<a[i].p){
now++;
tree_update(now,);
}
int pos=a[i].id;
);
);
}
; i<=q; i++) printf("%d\n", (ans[i].R-ans[i].L+MOD)%MOD);
;
}
bzoj3083 遥远的国度 && bzoj3626 LCA (树链剖分)的更多相关文章
- [BZOJ3626] [LNOI2014]LCA(树链剖分)
[BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- BZOJ3626[LNOI2014]LCA——树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增
今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分
D. Happy Tree Party Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...
- BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )
说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...
- [CodeVS2370] 小机房的树 (LCA, 树链剖分, LCT)
Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花 ...
- bzoj 3626 : [LNOI2014]LCA (树链剖分+线段树)
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...
随机推荐
- JavaScript URL编码转换函数 encodeURIComponent()
encodeURIComponent()定义和用法 encodeURIComponent() 函数可把字符串作为 URI 组件进行编码. 语法:encodeURIComponent(URIstring ...
- Linux如何查看文件系统(磁盘使用情况)
查看磁盘剩余空间: df -Th 用法:df [选项]… [文件]… 显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统. 长选项必须用的参数在使用短选项时也是必须的. -a, ...
- POJ2195 最小费用流
题目:http://poj.org/problem?id=2195 处理出每个人到每个门的曼哈顿距离,分别建立容量为1费用为曼哈顿距离的边,在源点和每个人人之间建立容量为1费用为0的边,在门和汇点之间 ...
- C/C++ 的使用
C++ http://www.cplusplus.com/ http://www.cplusplus.me/ *****************容器container vector 转自 htt ...
- Maven No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 问题
maven编译项目时出错,提示信息如下: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3 ...
- Python自动化之django的ORM
django ORM操作 1.什么是ORM? ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作 ...
- python基础六
模块 1.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻辑上 ...
- Spring MVC+FreeMarker简介
最近做项目,刚接触到SpringMVC与FreeMarker框架,就简单介绍一下自己的理解,不正确的地方请大家指教!! 1.Spring MVC工作原理: 用户发送请求--->前端服务器去找相对 ...
- MySQL 5.7 学习:新增配置参数
背景: 继上次介绍 初识 MySQL 5.6 新功能.参数完之后,刚好MySQL 5.7又GA了,在官方测试里看到,MySQL5.7在功能.性能.可用性.安全和监控上又提升了很高.现在看看和MySQL ...
- day2
三级菜单: ))))))))))] last_levels.pop() ]]]]]]]]:] information = : ch = msvcrt.getch() ][][: : password= ...