[Codeforces 487E]Tourists

Description

题库链接

给你张 \(n\) 个点 \(m\) 条边的连通无向图。 \(q\) 次操作,让你支持:

  1. 询问可以出现在两点之间的简单路路径上的点的最小权值;
  2. 修改某个点的点权。

\(1\leq n, m, q\leq 10^5\)

Solution

显然在路径上如果存在一个点双,那么这个点双上的点是都能被经过的。

显然我们可以构建圆方树,方点维护点双中所有的点的点权,用堆实现。

值得注意的是,由于可能一个圆点周围有许多方点,如果更新时在每个方点内都更新的话,复杂度还是不正确的。所以我们规定每个方点只管辖其儿子的圆点。在求 \(lca\) 处特判一下即可。

Code

//It is made by Awson on 2018.3.17
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1e5, INF = ~0u>>1;
void read(int &x) {
    char ch; bool flag = 0;
    for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }

int X, n, m, q, u, v, a[(N<<1)+5]; char ch[3];
struct Edge {int u, v; };
struct Heap {
    priority_queue<int, vector<int>, greater<int> >p, q;
    void erase(int o) {q.push(o); }
    void push(int o) {p.push(o); }
    int top() {while (!q.empty() && p.top() == q.top()) p.pop(), q.pop(); return p.top(); }
}Q[(N<<1)+5];
stack<Edge>S;
int dfn[N+5], low[N+5], sccno[N+5], times, sccnum, pos;
int fa[(N<<1)+5], size[(N<<1)+5], dep[(N<<1)+5], top[(N<<1)+5], son[(N<<1)+5], idx[(N<<1)+5], b[(N<<1)+5];
struct graph {
    struct tt {int to, next; }edge[(N<<2)+5];
    int path[(N<<1)+5], top;
    void add(int u, int v) {edge[++top].to = v, edge[top].next = path[u], path[u] = top; }
}g1, g2;
struct Segment_tree {
#define lr(o) (o<<1)
#define rr(o) (o<<1|1)
    int sgm[(N<<3)+5];
    void build (int o, int l, int r) {
    if (l == r) {sgm[o] = a[b[l]]; return; } int mid = (l+r)>>1;
    build(lr(o), l, mid), build(rr(o), mid+1, r);
    sgm[o] = Min(sgm[lr(o)], sgm[rr(o)]);
    }
    int query(int o, int l, int r, int a, int b) {
    if (a <= l && r <= b) return sgm[o]; int mid = (l+r)>>1;
    int c1 = INF, c2 = INF;
    if (a <= mid) c1 = query(lr(o), l, mid, a, b);
    if (b > mid) c2 = query(rr(o), mid+1, r, a, b);
    return Min(c1, c2);
    }
    void insert(int o, int l, int r, int loc) {
    if (l == r) {sgm[o] = a[b[l]]; return; } int mid = (l+r)>>1;
    if (loc <= mid) insert(lr(o), l, mid, loc); else insert(rr(o), mid+1, r, loc);
    sgm[o] = Min(sgm[lr(o)], sgm[rr(o)]);
    }
}T;

void tarjan(int o, int fa) {
    dfn[o] = low[o] = ++times;
    for (int i = g1.path[o]; i; i = g1.edge[i].next) {
    int v = g1.edge[i].to;
    if (!dfn[v]) {
        S.push((Edge){o, v});
        tarjan(v, o); low[o] = Min(low[o], low[v]);
        if (low[v] >= dfn[o]) {
        ++n; ++sccnum;
        while (true) {
            Edge e = S.top(); S.pop();
            if (sccno[e.u] != sccnum) sccno[e.u] = sccnum, g2.add(n, e.u), g2.add(e.u, n);
            if (sccno[e.v] != sccnum) sccno[e.v] = sccnum, g2.add(n, e.v), g2.add(e.v, n);
            if (e.u == o && e.v == v) break;                    
        }
        }
    }else if (v != fa) low[o] = Min(low[o], dfn[v]);
    }
}
void dfs1(int o, int depth, int father) {
    fa[o] = father, dep[o] = depth, size[o] = 1;
    for (int i = g2.path[o]; i; i = g2.edge[i].next)
    if (g2.edge[i].to != father) {
        if (o >= X) Q[o].push(a[g2.edge[i].to]);
        dfs1(g2.edge[i].to, depth+1, o);
        size[o] += size[g2.edge[i].to];
        if (size[g2.edge[i].to] > size[son[o]]) son[o] = g2.edge[i].to;
    }
    if (o > X) a[o] = Q[o].top();
}
void dfs2(int o, int tp) {
    top[o] = tp, idx[o] = ++pos, b[pos] = o;
    if (son[o]) dfs2(son[o], tp);
    for (int i = g2.path[o]; i; i = g2.edge[i].next)
    if (g2.edge[i].to != fa[o] && g2.edge[i].to != son[o])
        dfs2(g2.edge[i].to, g2.edge[i].to);
}
int query(int u, int v) {
    int ans = INF, t;
    while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) Swap(u, v);
    t = T.query(1, 1, n, idx[top[u]], idx[u]);
    ans = Min(ans, t); u = fa[top[u]];
    }
    if (dep[u] < dep[v]) Swap(u, v);
    t = T.query(1, 1, n, idx[v], idx[u]); ans = Min(ans, t);
    if (v > X) t = T.query(1, 1, n, idx[fa[v]], idx[fa[v]]), ans = Min(ans, t);
    return ans;
}
void update(int o, int val) {
    if (fa[o]) Q[fa[o]].erase(a[o]);
    a[o] = val; T.insert(1, 1, n, idx[o]);
    if (fa[o]) Q[fa[o]].push(a[o]), a[fa[o]] = Q[fa[o]].top(), T.insert(1, 1, n, idx[fa[o]]);
}
void work() {
    read(n), read(m), read(q); X = n;
    for (int i = 1; i <= n; i++) read(a[i]);
    for (int i = 1; i <= m; i++) read(u), read(v), g1.add(u, v), g1.add(v, u);
    tarjan(1, 0); dfs1(1, 1, 0); dfs2(1, 1); T.build(1, 1, n);
    while (q--) {
    scanf("%s", ch); read(u), read(v);
    if (ch[0] == 'A') writeln(query(u, v));
    else update(u, v);
    }
}
int main() {
    work(); return 0;
}

转载于:https://www.cnblogs.com/NaVi-Awson/p/8588195.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值