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 函数与对象
javascript中的函数是非常重要的概念,也是比较难于理解的一个知识点! 下面就来聊聊函数: JS基于对象:什么是基于对象呢?简单的说所有代码都是"对象"; 比如函数: fun ...
- UI第九节——UIProgressView
- (void)viewDidLoad { [super viewDidLoad]; // 实例化 UIProgressView,高度是固定的 UIProgressView ...
- 【bzoj2318】Spoj4060 game with probability Problem
题目描述 Alice和Bob在玩一个游戏.有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事.取到最后一颗石子的人胜利.Alice在投掷硬币时有 ...
- jQuery如何退出each循环的?
试问:jQuery是如何退出each循环的? 在回调函数里return false即可,大多数jQuery的方法都是如此的. 返回 'false' , 将停止循环 (就像在普通的循环中使用 'bre ...
- 修改mysql默认字符编码出现的Job failed to start解决方法
5.5以后的版本对字符编码方式修改的办法,原来在[mysqld]下的修改已经发生了变化,正确方式如下: [mysqld]下添加的应该为: character-set-server=utf8 colla ...
- espcms简约版的表单,提示页,搜索列表页
模板/lib/form.html <script type="text/javascript" src="{%$rootdir%}js/My97DatePicker ...
- MyEclipse 10, 2013, 2014 破解、注册码
MyEclipse 试用期限一般是三十天,过了三十天后 MyEclipse 会提示用户注册而不能正常使用,这里分享一下破解过程,仅供学习和参考. MyEclipse 10, 2013, 2014 破解 ...
- java学习第三天 数组
java中数组一样存在多维,二维数组,三维数组..... 二维数组的定义 格式: 数据类型 [][] 数组名 = new 数据类型 [][]; 动态初始化 数据类型[][] 数组名 = new 数 ...
- Jquery表单提交后获取返回Json值
1.给form添加id值: <form action="/News/SaveMessage" method="post" accept-charset=& ...
- C++ 基础知识复习(六)
操作系统部分: 79. 操作系统的最小调度单位:线程. 线程thread,进程process.一个进程至少包含一个线程,主线程,main thread. 80. 资源的最小单位是:进程. 81. 进程 ...