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 ...
随机推荐
- VS2008 Debug与Release的本质区别(转)
如何设置:工具栏“生成”→“配置管理器”→“活动解决方案配置” 对于VS2008的初次使用者来说,常会遇到的编译问题时,Debug版本运行正常,但在Release版本则不稳定或无法运行.以下是对Deb ...
- Discuzx系统 CSS 编码规范,CSS属性书写顺序
1. 属性写在一行内,属性之间.属性名和值之间以及属性与“{}”之间须有空格,例如:.class { width: 400px; height: 300px; } 2. 属性的书写顺序: ...
- CentOS6.3 编译安装LAMP(2):编译安装 Apache2.4.6
Apache官方说: 与Apache 2.2.x相比,Apache 2.4.x提供了很多性能方面的提升,包括支持更大流量.更好地支持云计算.利用更少的内存处理更多的并发等.除此之外,还包括性能提升.内 ...
- 支持向量机SVM
SVM(Support Vector Machine)有监督的机器学习方法,可以做分类也可以做回归.SVM把分类问题转化为寻找分类平面的问题,并通过最大化分类边界点距离分类平面的距离来实现分类. 有好 ...
- GitHub使用教程
一直以来都想使用Git来管理自己平时积累的小代码,就是除了工作之外的代码了.有时候自己搞个小代码,在公司写了,就要通过U盘或者网盘等等一系列工具进行Copy,然后回家才能继续在原来的基础上作业.Cop ...
- MySql连接数据库和操作(java)
package org.wxd.weixin.util; import java.sql.Connection;import java.sql.DriverManager;import java.sq ...
- Python日志logging
logging 用于便捷记录日志且线程安全的模块 1.单文件日志 import logging logging.basicConfig(filename='log.log', format='%(as ...
- 最简单的js确认框!
随便举个栗子~ function bremove() { if (ids == "") {//触发函数,如果值是空弹框 alert("您还没有选择任何数据.") ...
- jquery写简单的div切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Effective C++阅读笔记_条款2:尽量以const,enum,inline替换#define
1.#define缺点1 #define NUM 1.2 记号NUM可能没有进入记号表,在调试或者错误信息中,无法知道1.2的含义. 改善:通过const int NUM = 1.2; 2.#dein ...