Tourists

CodeForces - 487E


题意:有N个点,M条边,有Q次询问,每次有两种询问的方式:

  1. C X Y 将X点的权值改变成Y
  2. A U V询问从u到v的不经过重复点的路径上的最小点权

所以,看到有环的问题,就是直接往圆方树上套了,直接缩点,然后我们对缩点之后的树进行处理,于是我不经过任何优化的TLE在了第18组。为什么会TLE呢?其实很简单,就是我们需要去给方点保存权值,影响方点的权值是它周围所有的点,它的父亲结点,和它的子结点,很显然一件事就是当我们更新一个点的时候,它作为父亲结点的时候,会影响的方点比较多的时候,我们会直接使得复杂度上升到,这显然是我们不愿意看到的,于是猜测了一发数据随机交了试了试水,TLE。

那么,就是优化方点的问题了,其实突破口也是在方点的父亲上,如果说我们把方点的权值定义为其儿子结点的最小值的话,那么可以使用每次单点更新的复杂度降至级别的,又能够发现,所有的方点的父亲,如果我们的LCA会经过它的父亲,那么它的父亲的贡献实际上是已经算进去了,如果说,我们跑LCA没经过它的父亲,那么只有一种可能,它就是LCA点,所以,对于方点是LCA点的时候,我们再特别判断一下即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7, maxM = 2e5 + 7;
int N, M, Q, w[maxN];
struct Graph
{int head[maxN], cnt;struct Eddge{int nex, to;Eddge(int a=-1, int b=0):nex(a), to(b) {}} edge[maxM << 1];inline void addEddge(int u, int v){edge[cnt] = Eddge(head[u], v);head[u] = cnt++;}inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }inline void init(){cnt = 0;for(int i=1; i<=N; i++) head[i] = -1;}
} Old, Now;
int dfn[maxN], tot, low[maxN], Stap[maxN], Stop, Bcnt;
multiset<int> st[maxN];
multiset<int>::iterator it;
void Tarjan(int u, int fa)
{dfn[u] = low[u] = ++tot;Stap[++Stop] = u;for(int i=Old.head[u], v, p; ~i; i=Old.edge[i].nex){v = Old.edge[i].to;if(v == fa) continue;if(!dfn[v]){Tarjan(v, u);low[u] = min(low[u], low[v]);if(low[v] >= dfn[u]){Bcnt++; Now.head[Bcnt + N] = -1;do{p = Stap[Stop--];Now._add(p, N + Bcnt);} while(p ^ v);Now._add(u, N + Bcnt);}}else low[u] = min(low[u], dfn[v]);}
}
int siz[maxN], Wson[maxN], deep[maxN], fa[maxN];
void dfs_1(int u, int father)
{deep[u] = deep[father] + 1; siz[u] = 1; fa[u] = father;if(father > N) { st[father - N].insert(w[u]); }int maxx = 0;for(int i=Now.head[u], v; ~i; i=Now.edge[i].nex){v = Now.edge[i].to;if(v == father) continue;dfs_1(v, u);if(siz[v] > maxx){maxx = siz[v];Wson[u] = v;}siz[u] += siz[v];}
}
int top[maxN], id[maxN], _Index, Wv[maxN];
void dfs_2(int u, int topy)
{top[u] = topy; id[u] = ++_Index; Wv[_Index] = u > N ? (*st[u - N].begin()) : w[u];if(Wson[u]) dfs_2(Wson[u], topy);for(int i=Now.head[u], v; ~i; i=Now.edge[i].nex){v = Now.edge[i].to;if(v == fa[u] || v == Wson[u]) continue;dfs_2(v, v);}
}
struct BIT_Tree
{int tree[maxN << 2];void buildTree(int rt, int l, int r){if(l == r) { tree[rt] = Wv[l]; return; }int mid = HalF;buildTree(Lson); buildTree(Rson);tree[rt] = min(tree[lsn], tree[rsn]);}void update(int rt, int l, int r, int qx, int val){if(l == r) { tree[rt] = val; return; }int mid = HalF;if(qx <= mid) update(Lson, qx, val);else update(Rson, qx, val);tree[rt] = min(tree[lsn], tree[rsn]);}int query(int rt, int l, int r, int ql, int qr){if(ql <= l && qr >= r) return tree[rt];int mid = HalF;if(qr <= mid) return query(QL);else if(ql > mid) return query(QR);else return min(query(QL), query(QR));}inline int Q_Range(int u, int v){int ans = INF;while(top[u] ^ top[v]){if(deep[top[u]] < deep[top[v]]) swap(u, v);ans = min(ans, query(1, 1, N + Bcnt, id[top[u]], id[u]));u = fa[top[u]];}if(deep[u] < deep[v]) swap(u, v);ans = min(ans, query(1, 1, N + Bcnt, id[v], id[u]));if(v > N) ans = min(ans, w[fa[v]]);return ans;}inline void Point_update(int u, int val){int p = fa[u] - N;if(p > 0){it = st[p].find(w[u]);st[p].erase(it);st[p].insert(val);update(1, 1, N + Bcnt, id[p + N], *st[p].begin());}w[u] = val; Wv[id[u]] = val;update(1, 1, N + Bcnt, id[u], val);}
} tree;
inline void init()
{tot = Bcnt = Stop = _Index = 0;Old.init(); Now.init();
}
int main()
{scanf("%d%d%d", &N, &M, &Q); init();for(int i=1; i<=N; i++) scanf("%d", &w[i]);for(int i=1, u, v; i<=M; i++){scanf("%d%d", &u, &v);Old._add(u, v);}for(int i=1; i<=N; i++) if(!dfn[i]) Tarjan(i, 0);dfs_1(1, 0);dfs_2(1, 1);tree.buildTree(1, 1, N + Bcnt);char op[3]; int x, y;while(Q--){scanf("%s%d%d", op, &x, &y);if(op[0] == 'C') tree.Point_update(x, y);else printf("%d\n", tree.Q_Range(x, y));}return 0;
}

Tourists【广义圆方树+树链剖分+方点的特别优化】相关推荐

  1. CodeForces - 1437G Death DBMS(AC自动机fail树上树链剖分建线段树/暴跳fail)

    题目链接:点击查看 题目大意:给出 n 个模式串,每个模式串初始时的权值为 0,然后有 m 次操作: 1 i x:将第 i 个模式串的权值修改为 x 2 s:给出一个字符串 s,询问字符串 s 作为主 ...

  2. 个人赛C 柠檬树2--树链剖分+维护最值出现次数/LCA

    给一棵树,维护上面两点最短路径中结点的最大值及最大值出现次数 #include <stdio.h> #include<string.h> #include<algorit ...

  3. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  4. [十二省联考2019]春节十二响——长链剖分+堆

    题目链接: [十二省联考2019]春节十二响 可以发现每条链上的所有点都要放在不同的段里,那么最多只需要树的深度这么多段就够了. 因为这样可以保证每条链上的点可以放在不同的段中而且一个点放在这些段中一 ...

  5. 广义圆方树+树链剖分+set(Codeforces Round #278 (Div. 1): E. Tourists)

    前置:双联通分量.圆方树.树链剖分 什是是广义圆方树 圆方树是针对于仙人掌建树,而广义圆方树是针对无向图建树,对于一个无向图 无向图中的所有点 → 广义圆方树中的所有圆点 无向图中的一个双联通分量 → ...

  6. 【CF487E】Tourists【圆方树】【树链剖分】【multiset】

    题意:给一张 nnn 点 mmm 边的连通无向图,点帯权,qqq 次操作: 修改一个点的权值. 询问两点间所有简单路的最小权值的最小值. n,m,q≤105n,m,q\leq 10^5n,m,q≤10 ...

  7. CF487E Tourists(圆方树+树链剖分)

    洛谷题目传送门 解题思路 不会圆方树的可以看我的博客圆方树学习记录及例题 首先Tarjan寻找点双连通分量,然后建立圆方树,每个方点存这个点双内的最小点权 将圆方树树链剖分之后,对于修改操作,将这个点 ...

  8. 5909. 【NOIP2018模拟10.16】跑商(圆方树+树链剖分+SET)

    题目大意: 基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从任意一个点出发并在起点购买货物,在旅途中任意一点卖出并最终到达终点,尊者神高达的时间很宝贵,所以他不会重复经过同一个城市,但 ...

  9. [JZOJ5909]【NOIP2018模拟10.16】跑商【圆方树】【树链剖分】

    Description 基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从某个点出发并在起点购买货物,在旅途中任意一点卖出并最终到达终点,尊者神高达的时间很宝贵,所以他不会重复经过同一个 ...

  10. [树链剖分][圆方树] Jzoj P5909 跑商

    Description 题目背景: 尊者神高达很穷,所以他需要跑商来赚钱 题目描述: 基三的地图可以看做 n 个城市,m 条边的无向图,尊者神高达会从任意一个点出发并在起点购买货物,在旅途中任意一点卖 ...

最新文章

  1. 鸡啄米vc++2010系列32(标签控件Tab Control 下)
  2. OKR案例:德勤如何引入OKR
  3. PowerShell学习笔记(三)
  4. spring-boot-mybatis
  5. 9.切换 iframe
  6. ChaosConf 2018:混沌实验的演变
  7. Unicode、UTF-8、Big Endian、Little Endian、GBK、UCS-2
  8. php业务网站资源网,企业创意业务网站模板
  9. Arrays.asList()的坑
  10. excel制作跨职能流程图_用Excel规划求解工具,实现组合投资优化
  11. win7下chm打不开
  12. java 调用 fastreport,Winform中使用FastReport实现简单的自定义PDF导出
  13. QuickTime不支持播放HEVC编码mp4/mov视频
  14. NOIP2010 机器翻译 题解
  15. 网络实名认证接口认证形式有哪些?
  16. 【热门主题:萤火之夜xp桌面】
  17. 从UIL库谈Android图片加载中需要注意的事情
  18. 为快乐工作而生的协同办公管理平台——IBOS!
  19. 分布式事务—Lec12课前资料
  20. 通达信公式-接近均线

热门文章

  1. 电影《绿箭侠第一季》迅雷中英双字下载地址
  2. 网页打印文档,不弹出浏览器打印对话框设计思路
  3. 1080i和1080p区别
  4. 推荐两款超高质量的壁纸软件
  5. 6572 Phone call分析
  6. 置信区间、P值那点事
  7. php各版本共存方法,PHP多版本共存解决方案图解
  8. IDEA运行项目时停不下来
  9. 有没有发现不会写简历,感觉什么都不会?其实写简历也是一种艺术。
  10. Centos7之LVM(逻辑卷管理器)