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 ...
随机推荐
- 1·3 对 git 的认识
我可以诚实的说:这是我第一次听见这个名词 GIT.老师您发的关于git链接我下载了,只是还没看完.所以以下只是片面的理解,在后期我会单独再发一次. 一·GIT的简单介绍 1·Git是一款免费.开源的分 ...
- c语言中的一些注意点
1.头文件两种形式的区别(#include<mystring.h>与#include"mystring.h") 当运行一个程序时,需要调用自己写的函数时,需要在头文件加 ...
- POJ推荐50题
此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...
- vux 获取后台数据
1. 首先,导入api 的组件 import api from '../vuex/action' 2.定义数据获取方法 created () { this.fetchData() }, 3.设置方法内 ...
- xcode8 info.plist文件中的各种权限。
NSContactsUsageDescription -> 通讯录 NSMicrophoneUsageDescription -> 麦克风 NSPhotoLibraryUsageDescr ...
- 火狐min-height不兼容解决方法
我们在进行页面架构的时候,一般会分成三个section:header.body.footer.如下面这个页面: 这个时候我们就需要对body部分进行最小高度设置,才能避免footer部分出现在页面中间 ...
- iOS - 使用自定义字体-苹方字体
苹方提供了六个字重,font-family 定义如下:苹方-简 常规体font-family: PingFangSC-Regular, sans-serif;苹方-简 极细体font-family: ...
- Android Studio增加NDK代码编译支持--Mac环境
Android的APP开发基本都是使用Java或者跨平台框架进行开发的,对于很多APP来说已经足够了,但是,对于提供功能给外部使用或者性能要求很高的需求下,如图像处理等,可能会需要C/C++库的支持, ...
- LeetCode之389. Find the Difference
-------------------------------------------------- 先计算每个字母的出现次数然后减去,最后剩下的那一个就是后来添加的了. AC代码: public c ...
- 关于Android 5.0 网络图标叹号的解决办法
那么下面就给出解决方法(无需root): 1.完全屏蔽网络检查功能,最简单快速,但是就没有办法提示wifi登录: adb shell "settings put global captive ...