当前位置:网站首页>【luogu CF487E】Tourists(圆方树)(树链剖分)(线段树)
【luogu CF487E】Tourists(圆方树)(树链剖分)(线段树)
2022-07-05 23:34:00 【SSL_TJH】
Tourists
题目链接:luogu CF487E
题目大意
给你一个无向图,然后点有点权。
然后每次可能会单点修改点权,或者询问两个点之间所有的路径中点权最小的点。
思路
看到这种所有路径不难想到圆方树。
然后我们考虑方点就是它连着的原点的最小值。
然后会发现如果有修改会每次被卡到 O ( n ) O(n) O(n)(大菊花)
然后考虑一个奇妙的方法,就是考虑这个图特殊的地方,它是一棵树。
那你被卡的原因是因为你要全部都更新,那更新是肯定要更新的,那问题是我们可不可以先只更新一部分,然后询问的时候把没有的部分弄上。
那树的结构的话我们是不是可以只弄儿子的,然后每次更新就只用更新父亲那个。
然后你想一下树链剖分的部分,那不就是除了 LCA 是方点要把它父亲弄上之外别的都没问题吗。
然后剩下的就简单了,就普通圆方树,普通树链剖分加线段树维护最小值。
代码
#include<set>
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 100;
int n, m, q, w[N << 1], tot;
vector <int> G[N], GG[N << 1];
multiset <int> sum[N];
struct SLPF {
int dfn[N << 1], son[N << 1], sz[N << 1], fa[N << 1], top[N << 1], a[N << 3], deg[N << 1], dy[N << 1];
void dfs1(int now, int father) {
sz[now] = 1; fa[now] = father; deg[now] = deg[father] + 1;
for (int i = 0; i < GG[now].size(); i++) {
int x = GG[now][i]; if (x == father) continue;
dfs1(x, now); sz[now] += sz[x]; if (sz[x] > sz[son[now]]) son[now] = x;
}
if (now > n) {
for (int i = 0; i < GG[now].size(); i++) {
int x = GG[now][i]; if (x == father) continue;
sum[now - n].insert(w[x]);
}
w[now] = *sum[now - n].begin();
}
}
void dfs2(int now, int father) {
dfn[now] = ++dfn[0]; dy[dfn[0]] = now;
if (son[now]) {
top[son[now]] = top[now]; dfs2(son[now], now);
}
for (int i = 0; i < GG[now].size(); i++) {
int x = GG[now][i]; if (x == father || x == son[now]) continue;
top[x] = x; dfs2(x, now);
}
}
void up(int now) {
a[now] = min(a[now << 1], a[now << 1 | 1]);
}
void build(int now, int l, int r) {
if (l == r) {
a[now] = w[dy[l]]; return ;
}
int mid = (l + r) >> 1;
build(now << 1, l, mid); build(now << 1 | 1, mid + 1, r);
up(now);
}
void change(int now, int l, int r, int pl) {
if (l == r) {
a[now] = w[dy[pl]]; return ;
}
int mid = (l + r) >> 1;
if (pl <= mid) change(now << 1, l, mid, pl); else change(now << 1 | 1, mid + 1, r, pl);
up(now);
}
int query(int now, int l, int r, int L, int R) {
if (L <= l && r <= R) {
return a[now];
}
int mid = (l + r) >> 1, re = 2e9;
if (L <= mid) re = min(re, query(now << 1, l, mid, L, R));
if (mid < R) re = min(re, query(now << 1 | 1, mid + 1, r, L, R));
return re;
}
int ask(int x, int y) {
int re = 2e9;
while (top[x] != top[y]) {
if (deg[top[x]] < deg[top[y]]) swap(x, y);
re = min(re, query(1, 1, tot, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if (deg[x] > deg[y]) swap(x, y);
re = min(re, query(1, 1, tot, dfn[x], dfn[y]));
if (x > n) re = min(re, w[fa[x]]);
return re;
}
}T;
struct YF_tree {
int dfn[N], low[N], sta[N];
void link(int x, int y) {
GG[x].push_back(y); GG[y].push_back(x);}
void tarjan(int now) {
dfn[now] = low[now] = ++dfn[0]; sta[++sta[0]] = now;
for (int i = 0; i < G[now].size(); i++) {
int x = G[now][i];
if (!dfn[x]) {
tarjan(x); low[now] = min(low[now], low[x]);
if (dfn[now] == low[x]) {
tot++;
while (sta[sta[0]] != x) {
link(sta[sta[0]], tot); sta[0]--;
}
link(sta[sta[0]], tot); sta[0]--;
link(now, tot);
}
}
else low[now] = min(low[now], dfn[x]);
}
}
void Init() {
tot = n;
for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i);
T.dfs1(1, 0); T.dfs2(1, 0);
}
}H;
int main() {
scanf("%d %d %d", &n, &m, &q);
for (int i = 1; i <= n; i++)
scanf("%d", &w[i]);
for (int i = 1; i <= m; i++) {
int x, y; scanf("%d %d", &x, &y);
G[x].push_back(y); G[y].push_back(x);
}
H.Init();
T.build(1, 1, tot);
while (q--) {
char c = getchar(); while (c != 'C' && c != 'A') c = getchar();
if (c == 'A') {
int x, y; scanf("%d %d", &x, &y);
printf("%d\n", T.ask(x, y));
}
else {
int x, y; scanf("%d %d", &x, &y);
if (T.fa[x]) {
sum[T.fa[x] - n].erase(w[x]); sum[T.fa[x] - n].insert(y);
w[T.fa[x]] = *sum[T.fa[x] - n].begin(); T.change(1, 1, tot, T.dfn[T.fa[x]]);
}
w[x] = y; T.change(1, 1, tot, T.dfn[x]);
}
}
return 0;
}
边栏推荐
- MySQL (2) -- simple query, conditional query
- Which side projects can be achieved? Is it difficult for we media to earn more than 10000 a month?
- Neural structured learning - Part 2: training with natural graphs
- Rasa 3. X learning series -rasa 3.2.1 new release
- 21. PWM application programming
- 带外和带内的区别
- Rasa 3.x 学习系列-Rasa X 社区版(免费版) 更改
- Breadth first search open turntable lock
- 进击的技术er——自动化
- Comparison of parameters between TVs tube and zener diode
猜你喜欢
Comparison of parameters between TVs tube and zener diode
PADS ROUTER 使用技巧小记
How to rotate the synchronized / refreshed icon (EL icon refresh)
《牛客刷verilog》Part III Verilog企业真题
Dynamic planning: robbing families and houses
Zero rhino technology joined hands with the intelligence Club: the "causal faction" forum was successfully held, and the "causal revolution" brought the next generation of trusted AI
Creative mode 1 - single case mode
Use mapper: --- tkmapper
Hcip course notes-16 VLAN, three-tier architecture, MPLS virtual private line configuration
零犀科技携手集智俱乐部:“因果派”论坛成功举办,“因果革命”带来下一代可信AI
随机推荐
The interface of grafana tool displays an error, incluxdb error
[classical control theory] summary of automatic control experiment
多普勒效应(多普勒频移)
Why use weak pointers for delegation- Why use weak pointer for delegation?
UVA11294-Wedding(2-SAT)
Attacking technology Er - Automation
21. PWM application programming
Comparison of parameters between TVs tube and zener diode
Idea connects to MySQL, and it is convenient to paste the URL of the configuration file directly
Spire.PDF for NET 8.7.2
Go language introduction detailed tutorial (I): go language in the era
Cwaitabletimer timer, used to create timer object access
Open source CRM customer relationship system management system source code, free sharing
Technical specifications and model selection guidelines for TVs tubes and ESD tubes - recommended by jialichuang
424. The longest repeated character after replacement ●●
零犀科技携手集智俱乐部:“因果派”论坛成功举办,“因果革命”带来下一代可信AI
4点告诉你实时聊天与聊天机器人组合的优势
Breadth first search open turntable lock
Live tiktok shop 2022 latest gameplay card slot overseas live e-commerce new traffic
2022.6.20-6.26 AI行业周刊(第103期):新的小生命