整理的算法模板合集: ACM模板



舒服,一次敲160行代码一次编译通过一次AC是真的爽!

虽然这道题可以当作简单版的树链剖分板子题了hhh

要求的是两条路径有没有交点,正解是LCA玄学证明,看的我有点懵,但是这道题可以用树链剖分呀,1e5的数据我们nlognnlognnlogn的树链剖分随便做。

问两条路径有没有交点,实际上我们可以直接用树链剖分直接暴力跑还不会超时,真的爽!我们只需要每次暴力将两条路径权值+1,然后线段树维护一个最大值,看 tr[1].maxv 是不是等于2,如果等于2说明一定有一个点被赋值两次,所以一定是交点!(就算要找交点的id也可以直接找链接)

需要注意的是我们每次查询完一次之后要把他们再减掉,不然会对后面的答案造成影响,然后就是非常简单好写的树链剖分啦 (~ ̄▽ ̄)~

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>using namespace std;
typedef long long ll;
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;
const double eps = 1e-6;int n, m;
int root, mod;
int head[N], ver[M], nex[M], tot;
int a[N], a_after[N];
struct Tree
{int l, r;int lz;int maxv;
}tr[N * 4];
int son[N];
int id[N], fa[N], cnt, deep[N], sizes[N];
int top[N];void add(int x, int y)
{ver[tot] = y;nex[tot] = head[x];head[x] = tot ++ ;
}inline void pushup(int p){tr[p].maxv = max(tr[p << 1].maxv, tr[p << 1 | 1].maxv);
}inline void pushdown(int p)
{auto &root = tr[p], &left = tr[p << 1], &right = tr[p << 1 | 1];if(root.lz == 0)return ;left.lz += root.lz;right.lz += root.lz;left.maxv += root.lz;right.maxv += root.lz;root.lz = 0;
}void build(int p, int l, int r)
{tr[p] = {l, r, 0, 0};if(l == r){tr[p].maxv = a_after[l];return ;}int mid = l + r >> 1;build(p << 1, l, mid);build(p << 1 | 1, mid + 1, r);pushup(p);
}int query(int p, int l, int r)
{if(tr[p].l >= l && tr[p].r <= r){return tr[p].maxv;}pushdown(p);int mid = tr[p].l +tr[p].r >> 1;int res = 0;if(l <= mid)res = max(res, query(p << 1, l, r));if(r > mid)res = max(res, query(p << 1 | 1, l, r));return res;
}void modify(int p, int l, int r, int k)
{if(tr[p].l >= l && tr[p].r <= r){tr[p].lz += k;tr[p].maxv += k;return ;}int mid = tr[p].l + tr[p].r >> 1;pushdown(p);if(l <= mid)modify(p << 1, l, r, k);if(r > mid)modify(p << 1 | 1, l, r, k);pushup(p);return ;
}void dfs_son(int x, int father, int deeps)
{deep[x] = deeps;fa[x] = father;sizes[x] = 1;int max_son = -1;for(int i = head[x]; ~i; i = nex[i]){int y = ver[i];if(y == father)continue;dfs_son(y, x, deeps + 1);sizes[x] += sizes[y];if(sizes[y] > max_son)son[x] = y, max_son = sizes[y];}
}void dfs_build(int x, int topfa)
{id[x] = ++ cnt;a_after[cnt] = a[x];top[x] = topfa;if(!son[x])return ;dfs_build(son[x], topfa);for(int i = head[x]; ~i; i = nex[i]){int y = ver[i];if(y == fa[x] || y == son[x])continue;dfs_build(y, y);//每个节点都有从他自己开始的一个轻链}
}void update_range(int x, int y, int k)
{while(top[x] != top[y]){if(deep[top[x]] < deep[top[y]])swap(x, y);modify(1, id[top[x]], id[x], k);x = fa[top[x]];}if(deep[x] > deep[y])swap(x, y);modify(1, id[x], id[y], k);
}int main()
{memset(head, -1, sizeof head);scanf("%d%d", &n, &m);root = 1;for(int i = 1; i <= n - 1; ++ i){int x, y;scanf("%d%d", &x, &y);add(x, y);add(y, x);}dfs_son(root, 0, 1);dfs_build(root, root);build(1, 1, n);while(m -- ){int a1, a2, b1, b2;scanf("%d%d%d%d", &a1, &a2, &b1, &b2);update_range(a1, a2, 1);update_range(b1, b2, 1);if(tr[1].maxv == 2){puts("Y");}else puts("N");update_range(a1, a2, -1);update_range(b1, b2, -1);}
}

luogu P3398 仓鼠找sugar(树链剖分、求树上两条路径有没有交点,爽!)相关推荐

  1. luogu P3398 仓鼠找sugar

    P3398 仓鼠找sugar 224通过 860提交 题目提供者 fjzzq2002 标签 云端↑ 难度 提高+/省选- 时空限制 1s / 128MB 题目描述 小仓鼠的和他的基(mei)友(zi) ...

  2. P3398 仓鼠找sugar (倍增LCA)

    P3398 仓鼠找sugar (倍增LCA) 前言:本来想找 t a r j a n tarjan tarjan的题做下的,结果这个标签有 t a r j a n tarjan tarjan,却是 l ...

  3. [Luogu 3398] 仓鼠找sugar

    [Luogu 3398] 仓鼠找sugar 又是 LCA- 前两天死活写不过的一个题今天终于顺手切了. 思路嘛参考了一楼题解. 就是说,对于 a, b, c, d 四个点, 令 x = LCA(a, ...

  4. 【洛谷】【lca+结论】P3398 仓鼠找sugar

    [题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...

  5. 洛谷 P3398 仓鼠找 sugar

    仓鼠找 sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为 1 1 1~ n n n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室( a a ...

  6. P3398 仓鼠找sugar

    传送门(洛谷) 树链剖分(LCA) 题目分析,如果两个人会在路上相遇,则一个点的LCA一定在另一条链上,也就是        \;\;\; S = l c a ( a , b )    P = l c ...

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

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

  8. P3398 仓鼠找sugar(LCA,树剖)

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  9. 洛谷 3398 仓鼠找sugar 【模板】判断树上两链有交

    [题解] 题意就是判断树上两条链是否有交.口诀是"判有交,此链有彼祖".即其中一条链的端点的Lca在另一条链上. 我们设两条链的端点的Lca中深度较大的为L2,对L2与另一条链的两 ...

最新文章

  1. 大三本科生获最佳短论文奖,清华大学狂揽信息检索顶会SIGIR 2020多个奖项
  2. linux shell 调试 检查 脚本
  3. 继国美处罚“摸鱼”员工后,网易出品之摸鱼计算器...
  4. DCMTK:测试dcmiod的代码序列宏实现
  5. cobbler命令_使用Cobbler批量部署Linux和Windows:Windows系统批量安装(三)
  6. STM32工作笔记0098---Windows下的Linux环境_Cygwin_MinGW_MSYS_MSYS2_之间的关系
  7. Android开发问题汇总
  8. mt4双线macd_手机版MT4双线MACD设置视频教程
  9. Matlab利用gca设置图像属性(线型,字号,颜色)
  10. 【项目10】python+flask搭建CNN在线识别手写中文网站
  11. 金铜仙人辞汉歌-李贺
  12. 浏览器刷新+缓存原理
  13. EC20模块内置协议栈的开发笔记
  14. 飞思卡尔智能车—无线充电电源(节能组)
  15. 功率计和频谱仪测量功率的差异
  16. Mysql设计学生宿舍管理系统+考勤系统
  17. pyhton中r‘‘表达式的语法
  18. eyeOS 2.0安裝指南 - 中文版 (附英文版)zt
  19. PowerDesigner15.5 逆向生成mysql数据PDM文件
  20. Stall Reservations POJ - 3190(贪心+优先队列)

热门文章

  1. 100行代码搞定实时视频人脸表情识别(附代码)
  2. 基于CNN的图像缺陷分类
  3. 如何量化医学图像分割中的置信度?
  4. S-BEV:用于天气和光照不变的3-DoF定位的语义鸟瞰视图表示
  5. 【OpenCV 4开发详解】点集拟合
  6. 用链表生成前序二叉树
  7. Android 网络编程系列(5)Volley 网络框架入门
  8. Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解...
  9. 解决Wireshark 服务运行于非默认端口问题
  10. 使用metablog迁移博客园的文章