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 ...
随机推荐
- 问题--feed列表有新闻重复的问题
1. 经常有运营反应,客户端展示的feed列表有重复的问题. 重复问题分为两种,一种是两条新闻标题类似,另一种是两条新闻标题是完全相同. (1)标题类似 原来过滤的逻辑,是两个标题完全相等,才认为两条 ...
- JSON.parse和eval的区别
JSON.parse和eval的区别 JSON(JavaScript Object Notation)是一种轻量级的数据格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是Jav ...
- java final 关键字
1.修饰类当用final修饰一个类时,表明这个类不能被继承.也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰.final类中的成员变量可以根据需要设为final,但是要注意fina ...
- JavaScript之bind,call,apply
参考: http://rangercyh.blog.51cto.com/1444712/1615809 function foo(a,b) { this.x = this.x + a + b; } / ...
- C# 类动态添加属性、方法(Z)
问题: 需要动态为WPF中的DataGrid添加列,并动态绑定相应数据.(此处仅实现动态属性的添加和使用,关于动态方法的添加和使用详见推荐阅读) 实现关键点: 目标类继承DynamicObject ...
- Webdriver配合Tesseract-OCR 自动识别简单的验证码
验证码: 如下,在进行自动化测试,遇到验证码的问题,一般有两种方式 1.找开发去掉验证码或者使用万能验证码 2.使用OCR自动识别 使用OCR自动化识别,一般识别率不是太高,处理一般简单验证码还是没问 ...
- MVC4.0
--后台ajax传值 <script type="text/javascript"> $(document).ready(function dianZan(id ...
- .NET LINQ基本查询操作
获取数据源 在 LINQ 查询中,第一步是指定数据源.像在大多数编程语言中一样,在 C# 中,必须先声明变量,才能使用它.在 LINQ 查询中,最先使用 from 子句的目的是引入数据源 ( ...
- CoreAnimation 之CAReplicatorLayer
CAReplicatorLayer: 主要作用有以下两个: CAReplicatorLayer的目的是为了高效生成许多相似的图层,它会绘制一个或多个图层的子图层 并在每个复制体上应用不同的变换 使用C ...
- 解决xampp端口冲突
今天电脑按了一下xampp,结果运行wamp的时候,出现了下面的情况: 在网上查了一下,结果是端口被占用,然后我就手动修改了一下. 1.修改xampp的端口号 依次找到:XAMPP的安装目录(比如D: ...