今早刷了两道树剖的题目,用时两小时十五分钟= =

树剖的题目代码量普遍120+

其实打熟练之后是很容易调的,不熟练的话代码量大可能会因为某些小细节调很久

3083:裸树剖+“换根”

所谓换根其实只要判断一下当前询问点的子树和当前根的位置关系就好了,不能真的换根

根不在当前点的子树中则不影响;根在当前子树中,那么根所在的那部分子树不询问就可以了,而其他点都要询问

3626:这个题目很巧妙

有两个地方是很神的,一是将询问l~r转化为询问z一个点,二是离线操作O(qlog2n)就解决了询问

  1 //bzoj3083
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 #define INF 1000000010
  6 using namespace std;
  7 const int maxn = 100010;
  8 struct node{
  9     int l,r,lz,mn;
 10 }t[maxn*4];
 11 struct edge{
 12     int to,next;
 13 }e[maxn*2];
 14 int head[maxn],tot,n,Q,u,v,w,cap,size[maxn],fa[maxn],dep[maxn],top[maxn],son[maxn],tree[maxn],pre[maxn],cnt=0,v0[maxn],opt;
 15
 16 void insert(int u, int v){
 17     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
 18 }
 19
 20 void dfs1(int u, int f, int d){
 21     size[u]=1; fa[u]=f; dep[u]=d;
 22     for (int i=head[u]; i!=-1; i=e[i].next){
 23         int v=e[i].to; if (v==f) continue;
 24         dfs1(v,u,d+1);
 25         size[u]+=size[v];
 26         if (!son[u] || size[v]>size[son[u]]) son[u]=v;
 27     }
 28 }
 29
 30 void dfs2(int u, int num){
 31     top[u]=num; tree[u]=++cnt; pre[cnt]=u;
 32     if (!son[u]) return;
 33     dfs2(son[u],num);
 34     for (int i=head[u]; i!=-1; i=e[i].next)
 35         if (e[i].to!=fa[u] && e[i].to!=son[u]) dfs2(e[i].to,e[i].to);
 36 }
 37
 38 void pushup(int x){
 39     t[x].mn=min(t[x<<1].mn,t[x<<1|1].mn);
 40 }
 41
 42 void pushdown(int x){
 43     if (t[x].lz){
 44         t[x<<1].lz=t[x<<1|1].lz=t[x].lz;
 45         t[x<<1].mn=t[x<<1|1].mn=t[x].mn;
 46         t[x].lz=0;
 47     }
 48 }
 49
 50 void update(int a, int b, int w, int x){
 51     int l=t[x].l, r=t[x].r;
 52     if (l==a && r==b){
 53         t[x].lz=1;
 54         t[x].mn=w;
 55         return;
 56     }
 57     int mid=l+r>>1;
 58     pushdown(x);
 59     if (a>mid) update(a,b,w,x<<1|1);
 60     else if (b<=mid) update(a,b,w,x<<1);
 61     else update(a,mid,w,x<<1),update(mid+1,b,w,x<<1|1);
 62     pushup(x);
 63 }
 64
 65 int get_min(int a, int b, int x){
 66     int l=t[x].l, r=t[x].r;
 67     if (l==a && b==r) return t[x].mn;
 68     int mid=l+r>>1;
 69     pushdown(x);
 70     if (b<=mid) return get_min(a,b,x<<1);
 71     else if (a>mid) return get_min(a,b,x<<1|1);
 72     else return min(get_min(a,mid,x<<1),get_min(mid+1,b,x<<1|1));
 73 }
 74
 75 void build(int l, int r, int x){
 76     t[x].l=l, t[x].r=r;
 77     if (l==r){
 78         t[x].mn=v0[pre[l]];
 79         t[x].lz=0;
 80         return;
 81     }
 82     int mid=l+r>>1;
 83     if (l<=mid) build(l,mid,x<<1);
 84     if (r>mid) build(mid+1,r,x<<1|1);
 85     pushup(x);
 86 }
 87
 88 void change(int x, int y, int c){
 89     while (top[x]!=top[y]){
 90         if (dep[x]<dep[y]) swap(x,y);
 91         update(tree[top[x]],tree[x],c,1);
 92         x=fa[top[x]];
 93     }
 94     if (dep[x]>dep[y]) swap(x,y);
 95     update(tree[x],tree[y],c,1);
 96 }
 97
 98 int main(){
 99     scanf("%d%d", &n, &Q); tot=1; memset(head,-1,sizeof(head)); cnt=0;
100     for (int i=1; i<n; i++) scanf("%d%d", &u, &v),insert(u,v),insert(v,u);
101     dfs1(1,0,1);
102     dfs2(1,1);
103     for (int i=1; i<=n; i++) scanf("%d", &v0[i]);
104     build(1,cnt,1);
105     scanf("%d", &cap);
106     while (Q--){
107         scanf("%d", &opt);
108         if (opt==1) scanf("%d", &cap);
109         if (opt==2){
110             scanf("%d%d%d", &u, &v, &w);
111             change(u,v,w);
112         }
113         if (opt==3){
114             scanf("%d", &u);
115             if (u==cap) printf("%d\n", t[1].mn);
116             else{
117                 int child=0;
118                 for (int i=head[u]; i!=-1; i=e[i].next){
119                     int v=e[i].to;
120                     if (v==fa[u]) continue;
121                     if (tree[v]<=tree[cap] && tree[cap]<=tree[v]+size[v]-1) child=v;
122                 }
123                 if (child){
124                     int left=min(INF,get_min(1,tree[child]-1,1));
125                     int right=INF;
126                     if (tree[child]+size[child]<=cnt) right=min(right,get_min(tree[child]+size[child],cnt,1));
127                     printf("%d\n", min(min(left,right),get_min(tree[u],tree[u],1)));
128                 }
129                 else printf("%d\n", get_min(tree[u],tree[u]+size[u]-1,1));
130             }
131         }
132     }
133     return 0;
134 }

View Code

  1 //bzoj3626
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 #define MOD 201314
  6 using namespace std;
  7 const int maxn = 50010;
  8 struct node{
  9     int l,r,lz,sum,len;
 10 }t[maxn*4];
 11 struct edge{
 12     int to,next;
 13 }e[maxn*2];
 14 struct Ans{
 15     int z,R,L;
 16 }ans[maxn];
 17 struct cover{
 18     int p,id;
 19     bool flag;
 20 }a[maxn*2];
 21 int fa[maxn],dep[maxn],size[maxn],top[maxn],son[maxn],head[maxn],tot,cnt;
 22 int tree[maxn],pre[maxn],n,q,u,v;
 23
 24 bool cmp(cover a, cover b){
 25     return a.p<b.p;
 26 }
 27
 28 void insert(int u, int v){
 29     e[++tot].to=v; e[tot].next=head[u]; head[u]=tot;
 30 }
 31
 32 void dfs1(int u, int f, int d){
 33     fa[u]=f; dep[u]=d; size[u]=1;
 34     for (int i=head[u]; i!=-1; i=e[i].next){
 35         int v=e[i].to; if (v==f) continue;
 36         dfs1(v,u,d+1);
 37         size[u]+=size[v];
 38         if (!son[u] || size[v]>size[son[u]]) son[u]=v;
 39     }
 40 }
 41
 42 void dfs2(int u, int num){
 43     top[u]=num; tree[u]=++cnt; pre[cnt]=u;
 44     if (!son[u]) return;
 45     dfs2(son[u],num);
 46     for (int i=head[u]; i!=-1; i=e[i].next)
 47         if (e[i].to!=son[u] && e[i].to!=fa[u]) dfs2(e[i].to,e[i].to);
 48 }
 49
 50 void pushup(int x){
 51     t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
 52 }
 53
 54 void pushdown(int x){
 55     if (t[x].lz){
 56         t[x<<1].lz+=t[x].lz;
 57         t[x<<1|1].lz+=t[x].lz;
 58         t[x<<1].sum+=t[x<<1].len*t[x].lz;
 59         t[x<<1|1].sum+=t[x<<1|1].len*t[x].lz;
 60         t[x].lz=0;
 61     }
 62 }
 63
 64 int query(int a, int b, int x){
 65     int l=t[x].l, r=t[x].r;
 66     if (l==a && r==b) return t[x].sum;
 67     int mid=l+r>>1;
 68     pushdown(x);
 69     if (b<=mid) return query(a,b,x<<1);
 70     else if (a>mid) return query(a,b,x<<1|1);
 71     else return query(a,mid,x<<1)+query(mid+1,b,x<<1|1);
 72 }
 73
 74 void update(int a, int b, int x){
 75     int l=t[x].l, r=t[x].r;
 76     if (l==a && r==b){
 77         t[x].sum+=t[x].len;
 78         t[x].lz++;
 79         return;
 80     }
 81     int mid=l+r>>1;
 82     pushdown(x);
 83     if (b<=mid) update(a,b,x<<1);
 84     else if (a>mid) update(a,b,x<<1|1);
 85     else update(a,mid,x<<1),update(mid+1,b,x<<1|1);
 86     pushup(x);
 87 }
 88
 89 void build(int l, int r, int x){
 90     t[x].l=l, t[x].r=r; t[x].len=r-l+1;
 91     if (l==r){
 92         t[x].sum=0;
 93         t[x].lz=0;
 94         return;
 95     }
 96     int mid=l+r>>1;
 97     if (l<=mid) build(l,mid,x<<1);
 98     if (r>mid) build(mid+1,r,x<<1|1);
 99     pushup(x);
100 }
101
102 void tree_update(int x, int y){
103     while (top[x]!=top[y]){
104         if (dep[x]<dep[y]) swap(x,y);
105         update(tree[top[x]],tree[x],1);
106         x=fa[top[x]];
107     }
108     if (dep[x]>dep[y]) swap(x,y);
109     update(tree[x],tree[y],1);
110 }
111
112 int tree_query(int x, int y){
113     int ret=0;
114     while (top[x]!=top[y]){
115         if (dep[x]<dep[y]) swap(x,y);
116         ret+=query(tree[top[x]],tree[x],1); ret%=MOD;
117         x=fa[top[x]];
118     }
119     if (dep[x]>dep[y]) swap(x,y);
120     return (query(tree[x],tree[y],1) % MOD +ret) % MOD;
121 }
122
123 int main(){
124     scanf("%d%d", &n, &q);
125     tot=1; memset(head,-1,sizeof(head));
126     for (int i=1; i<n; i++){
127         scanf("%d", &u);
128         insert(u,i);
129     }
130     cnt=0;
131     dfs1(0,0,1);
132     dfs2(0,0);
133     build(1,n,1);
134     cnt=0;
135     for (int i=1; i<=q; i++){
136         scanf("%d%d%d", &u, &v, &ans[i].z);
137         a[++cnt].p=u-1; a[cnt].id=i; a[cnt].flag=0;
138         a[++cnt].p=v; a[cnt].id=i; a[cnt].flag=1;
139     }
140     sort(a+1,a+1+cnt,cmp);
141     int now=-1;
142     for (int i=1; i<=cnt; i++){
143         while (now<a[i].p){
144             now++;
145             tree_update(now,0);
146         }
147         int pos=a[i].id;
148         if (!a[i].flag) ans[pos].L=tree_query(ans[pos].z,0);
149         else ans[pos].R=tree_query(ans[pos].z,0);
150     }
151     for (int i=1; i<=q; i++) printf("%d\n", (ans[i].R-ans[i].L+MOD)%MOD);
152     return 0;
153 }

View Code

转载于:https://www.cnblogs.com/mzl120918/p/5966291.html

bzoj3083 遥远的国度 bzoj3626 LCA (树链剖分)相关推荐

  1. BZOJ3626 LNOI2014 LCA 树链剖分

    题意:给定一棵树,每次询问给出l r z,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和 题解: 显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标 ...

  2. HDU - 6393 Traffic Network in Numazu(线段树+LCA+树链剖分+并查集)

    题目链接:点击查看 题目大意:给出一个由n个点和n条边组成的图,每条边都有权值,题目保证图是连通的,然后给出m个询问,每次询问分为两种形式: 0 x y:将第x条边的权值修改为y 1 x y:查询x- ...

  3. CF613D-Kingdom and its Cities【虚树,LCA,树链剖分,贪心】

    正题 题目链接:https://www.luogu.org/problem/CF613D 题目大意 一棵树,每次询问kkk个点,删除mmm个点要这些点两两不连通,求mmm的最小值. 解题思路 我们可以 ...

  4. HDU5266 LCA 树链剖分LCA 线段树

    HDU5266 LCA Description 给一棵 n 个点的树,Q 个询问 [L,R] : 求点 L , 点 L+1 , 点 L+2 -- 点 R 的 LCA. Input 多组数据. The ...

  5. 数据结构课程设计-神秘国度的爱情故事-LCA:tarjan+离线/树链剖分/暴力

    1.无脑暴力dfs:   O(n*m) 2.LCA/tarjan+离线处理: O(n+m) 3.LCA/树链剖分: O(nlogn+m)~O(nlogn+mlogn) 4.LCA/倍增思想(有空再补) ...

  6. POJ - 1330 Nearest Common Ancestors(树上倍增/树链剖分求LCA)

    题目链接:点击查看 题目大意:给出一棵有根树,我们需要求出两个点的lca 题目分析:因为题目说了是有根树,所以我们在建图的时候直接建有向图就好了,并且记录一下每个点的入度,建完图后找一下入度为0的点, ...

  7. jzoj3626-[LNOI2014]LCA【树链剖分,线段树】

    正题 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3626 题目大意 一棵树,每次给出(l,r,z)(l,r,z)(l,r,z)询问∑i ...

  8. 【树链剖分】LCA(P4211)

    正题 P4211 题目大意 给你一棵树,有m次询问,每次询问要回答∑i=lrdep[lca(x,i)]\sum_{i=l}^rdep[lca(x,i)]∑i=lr​dep[lca(x,i)] 解题思路 ...

  9. bzoj 3626: [LNOI2014]LCA(离线差分+树链剖分)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2885  Solved: 1133 [Submit][Sta ...

最新文章

  1. c++窗口管理系统是什么_优秀的食堂管理系统让你对校园生活更充满希望
  2. 生产环境一个like模糊匹配SQL优化
  3. wxWidgets:编写应用程序的快速指南
  4. java jtextarea 滚动条_java 在JTextArea中显示 滚动条
  5. JS获取移动端系统信息(操作系统、操作系统版本、横竖屏状态、设备类型、网络状态、生成浏览器指纹)...
  6. DB2 删除某用户下的所有表
  7. 酷安电脑版_2020年末 平板电脑购买推荐
  8. IoC 之 2.2 IoC 容器基本原理(贰)
  9. 掌握中台系统,需要了解哪些技术?
  10. DEDECMS安装遇到NO input files specified解决方案
  11. 作为一名优秀的软件测试工程师,需要具备哪些能力?
  12. debian 5常用软件包名称,及安装方法
  13. 如何把微信消息或者短信实时转发到另一个手机上
  14. JAVACC使用总结(四):LOOKAHEAD解决语法选择冲突的利刃
  15. 山峰和山谷 Ridges and Valleys
  16. AutoCAD Civil 3D坐标几何(COGO)输入
  17. 百度地图开发技术方案及解决办法
  18. 设计模式(四)行为型模式介绍及实例(上)
  19. Cache entry deserialization failed, entry ignored 错误解决
  20. ξσ Dicky's GuestBook σξ

热门文章

  1. Linux安装Tomcat(非Docker安装、开放端口)
  2. MAX31856多类型热电偶温度检测方案芯片详解,附可实现的STM32程序代码
  3. 英语作文模板句型,考试必背!
  4. 什么是无监督、监督、半监督学习
  5. cglib中Enhancer介绍
  6. 27款国外最新Photoshop色板
  7. jsp 实现查询功能
  8. 远程访问MySql数据库
  9. MySQL中事务的持久性实现原理
  10. 程序人生 | 大龄的程序员都到哪里去了?