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 ...
随机推荐
- UI第十三节——UIActionSheet
- (void)viewDidLoad { [super viewDidLoad]; UISwitch *swc = [[UISwitch alloc] initWithFrame ...
- kxbdSuperMarquee.js滚动的神器-推荐
http://code.ciaoca.com/jquery/kxbdmarquee/ 版本:jQuery v1.3.2+ 查看 Demo 下载 jQuery kxbdMarquee 文档目录 使用方法 ...
- redis 快速入门(win7)
0:介绍 百度百科or官网 1:下载 选择32位或者64 地址:https://github.com/dmajkic/redis/downloads 1.1下载后如图 1.2文件介绍 redis-s ...
- Tcl
Tcl(发音 tickle)是一种脚本语言.由John Ousterhout创建.TCL经常被用于快速原型开发 RAD.脚本编程.GUI编程和测试等方面. Expect Expect是 另外一种非常流 ...
- Java中String,StringBuffer与StringBuilder的差别
String 字符串常量: StringBuffer 字符串变量〈缓冲区〉(线程安全): StringBuilder 字符串变量〈缓冲区〉(非线程安全): 简要的说, String 类型和 Strin ...
- 9.JAVA中的正则表达式
一.JAVA中的正则表达式 1.概念:以某种特定的方式描述字符串 1.Java中正则表达式的规则 ? #{0,1}-?有一个-或者没有 \\ #表示一个" ...
- kkjcre1p: unable to spawn jobq slave process, slot 0, error 1089(Linux x86_64)补丁
在shutdown immediately的时候,alert Log出现如下错误信息,并且不能正常关闭 kkjcre1p: unable to spawn jobq slave process, sl ...
- hdu 5071(2014鞍山现场赛B题,大模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5071 思路:模拟题,没啥可说的,移动的时候需要注意top的变化. #include <iostr ...
- [原创]Centos7 内部常用软件升级计划
GCC 当前系统版本 gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
- NOI 2010 海拔 ——平面图转对偶图
[题目分析] 可以知道,所有的海拔是0或1 最小割转最短路,就可以啦 SPFA被卡,只能换DIJ [代码] #include <cstdio> #include <cstring&g ...