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 ...
随机推荐
- HDOJ 4652 Dice
期望DP +数学推导 Dice Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- Linux网络下载命令 wget 简介
wget 是一个命令行的下载工具.对于我们这些 Linux 用户来说,几乎每天都在使用它.下面为大家介绍几个有用的 wget 小技巧,可以让你更加高效而灵活的使用 wget. $ wget -r -n ...
- php gettext 多语言翻译
1.在window与linux下的多语言切换有些区别,主要putenv的设置区别. 参考链接:http://www.cnblogs.com/sink_cup/archive/2013/11/20/ub ...
- poj 1170
很高兴,这道题刚编译成功提交就AC了. 简单的多重背包,标算估计是5.6维动规.其实可以通过6进制压成一维.判定是一个特价方式是否可行只需自己推一下就行了,很简单(对应位上的数目标不小于特价所需条件) ...
- (备忘)Rect和RectF的区别
1.Rect的变量使用int类型,而RectF使用float类型. 2.一些方法区别 <1>.Rect类 equals(Object obj) (for some reason it as ...
- RobotFrameWork(二)Ride简单使用及快捷键
一.简单示例 注意:以下操作使用到快捷键的,请先确保没有与其他软件的快捷键设置冲突,比如sogou拼音.有道词典等等 1.启动ride 启动ride方法: 1) 通过界面图标 2) dos命令行: ...
- delphi 各新版本特性收集
delphi 各新版本特性收集 http://www.cnblogs.com/dreamszx/p/3602589.html
- strust1与strust2,springmvc三者之间的区别?
strust1与struts2的区别 1.struts2是基于webWork的一个全新的框架,比struts1学习更方便 Struts2主要是改进了Struts1的servlet和acti ...
- 导入excel数据到数据库
1.上传excel到服务器 jsp页面代码 <form action="actionname" method="post" id="form1& ...
- 解决ssh远程登陆linux显示-bash-4.1$
cp -pr /etc/skel/.bash* /home/test/ #/home/test是用户目录改变用户家目录:usermod -md /tmptest test