【题解】SDOI2014旅行
大概是一道树链剖分的裸题。可以看出如果不是查询相同宗教的这一点,就和普通的树链剖分毫无两样了。所以针对每一个宗教都单独开一棵线段树,变成单点修改+区间查询。只不过宗教数目很多,空间消耗太大所以只能开一棵总的再动态开点。
#include <bits/stdc++.h>
using namespace std;
#define maxn 200500
#define maxm 2000000
int n, q, cnp = , cnt, tot, root[maxn], name[maxn], head[maxn], w[maxn], c[maxn];
struct node
{
int id, size, fa, dep, hson, gra;
}P[maxn]; struct edge
{
int to, last;
}E[maxn]; struct tree
{
int sum, ext, lson, rson;
}T[maxm]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void add(int x, int y)
{
E[cnp].to = y, E[cnp].last = head[x], head[x] = cnp ++;
} struct Segament_Tree
{
int query1(int p, int l, int r, int L, int R)
{
if(l <= L && r >= R) return T[p].sum;
if(l > R || r < L) return ;
int mid = (L + R) >> ;
return query1(T[p].lson, l, r, L, mid) + query1(T[p].rson, l, r, mid + , R);
} int query2(int p, int l, int r, int L, int R)
{
if(l <= L && r >= R) return T[p].ext;
if(l > R || r < L) return ;
int mid = (L + R) >> ;
return max(query2(T[p].lson, l, r, L, mid), query2(T[p].rson, l, r, mid + , R));
} void update(int &p, int L, int R, int x, int w)
{
if(!p) p = ++ cnt;
if(L == R)
{
T[p].sum = T[p].ext = w;
return;
}
int mid = (L + R) >> ;
if(x <= mid) update(T[p].lson, L, mid, x, w);
else update(T[p].rson, mid + , R, x, w);
T[p].sum = T[T[p].lson].sum + T[T[p].rson].sum;
T[p].ext = max(T[T[p].lson].ext, T[T[p].rson].ext);
} }ST[maxn]; struct Heavy_Light_Decomposition
{
int dfs(int u)
{
P[u].size = ;
for(int i = head[u]; i; i = E[i].last)
{
int v = E[i].to;
if(v == P[u].fa) continue;
P[v].dep = P[u].dep + , P[v].fa = u;
dfs(v);
P[u].size += P[v].size;
if(P[v].size > P[P[u].hson].size) P[u].hson = v;
}
} int dfs2(int u, int anc)
{
P[u].id = ++ tot, P[u].gra = anc, name[tot] = u;
if(P[u].hson) dfs2(P[u].hson, anc);
for(int i = head[u]; i; i = E[i].last)
{
int v = E[i].to;
if(v == P[u].hson || v == P[u].fa) continue;
dfs2(v, v);
}
} void update1(int x, int r)
{
ST[c[x]].update(root[c[x]], , tot, P[x].id, );
ST[r].update(root[r], , tot, P[x].id, w[x]);
c[x] = r;
} void update2(int x, int t)
{
ST[c[x]].update(root[c[x]], , tot, P[x].id, t);
w[x] = t;
} void query1(int x, int y)
{
int tx = P[x].gra, ty = P[y].gra;
int r = c[x];
int ans = ;
while(tx != ty)
{
if(P[tx].dep < P[ty].dep) swap(x, y), swap(tx, ty);
ans += ST[r].query1(root[r], P[tx].id, P[x].id, , tot);
x = P[tx].fa, tx = P[x].gra;
}
if(P[x].dep < P[y].dep) swap(x, y), swap(tx, ty);
ans += ST[r].query1(root[r], P[y].id, P[x].id, , tot);
printf("%d\n", ans);
} void query2(int x, int y)
{
int tx = P[x].gra, ty = P[y].gra;
int r = c[x];
int ans = ;
while(tx != ty)
{
if(P[tx].dep < P[ty].dep) swap(x, y), swap(tx, ty);
ans = max(ans, ST[r].query2(root[r], P[tx].id, P[x].id, , tot));
x = P[tx].fa, tx = P[x].gra;
}
if(P[x].dep < P[y].dep) swap(x, y), swap(tx, ty);
ans = max(ans, ST[r].query2(root[r], P[y].id, P[x].id, , tot));
printf("%d\n", ans);
} }HLD; int main()
{
n = read(), q = read();
for(int i = ; i <= n; i ++)
w[i] = read(), c[i] = read();
for(int i = ; i < n; i ++)
{
int x = read(), y = read();
add(x, y), add(y, x);
}
HLD.dfs(), HLD.dfs2(, );
for(int i = ; i < maxn; i ++) root[i] = ++ cnt;
for(int i = ; i <= n; i ++) ST[c[i]].update(root[c[i]], , tot, P[i].id, w[i]);
for(int i = ; i <= q; i ++)
{
string s;
cin >> s;
int x = read(), y = read();
if(s[] == 'C')
{
if(s[] == 'C') HLD.update1(x, y);
else HLD.update2(x, y);
}
else
{
if(s[] == 'S') HLD.query1(x, y);
else HLD.query2(x, y);
}
}
return ;
}
【题解】SDOI2014旅行的更多相关文章
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 876 Solved: 446[Submit][Status][ ...
- [SDOI2014]旅行
洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...
- B20J_3231_[SDOI2014]旅行_树链剖分+线段树
B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...
- [luogu P3313] [SDOI2014]旅行
[luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...
- 洛谷 P3313 [SDOI2014]旅行 解题报告
P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...
- bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)
3531: [Sdoi2014]旅行 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2984 Solved: 1312[Submit][Status ...
- P3313 [SDOI2014]旅行
P3313 [SDOI2014]旅行 树链剖分+动态线段树(并不是lct) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...
- 3531: [Sdoi2014]旅行
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 1731 Solved: 772 [Submit][Statu ...
随机推荐
- MAC系统如何显示隐藏文件解决方法
苹果Mac OS 操作系统下,隐藏文件默认为隐藏状态,隐藏文件是否显示有多种方法可以设置. 方法一: 打开终端,输入命令行 1.显示Mac隐藏文件的命令: defaults write com.app ...
- maven-生命周期与插件
Maven的生命周期是抽象的,具体的操作由插件实现,类似于java的模板设计模式. 1.生命周期 认识生命周期 maven有clean.default.site三种生命周期,每种生命周期都包含一些阶段 ...
- 吐血分享:QQ群霸屏技术教程2017(活跃篇)
热门词的群排名,在前期优化准备充分的情况下,活跃度不失为必杀技. 在<吐血分享:QQ群霸屏技术(初级篇)>中,我们提及到热门词的群排名,有了前面的基础,我们就可以进入深度优化,实现绝对的霸 ...
- php 移动或重命名文件(图片)到另一目录下的方法有多种,这里只列出三种:
php 移动或重命名文件(图片)到另一目录下的方法有多种,这里只列出三种: 方法一:使用copy函数 格式:copy(source,destination) 将文件从 source ...
- 误删 EhCache 中的数据?
最近遇到一个问题:在使用ehcache时,通过CacheManager.getCache(chachename).get(key),获取相应的缓存内对象(当时这个对象是个list), 有个同事写个方法 ...
- (数据科学学习手札22)主成分分析法在Python与R中的基本功能实现
上一篇中我们详细介绍推导了主成分分析法的原理,并基于Python通过自编函数实现了挑选主成分的过程,而在Python与R中都有比较成熟的主成分分析函数,本篇我们就对这些方法进行介绍: R 在R的基础函 ...
- 2844: albus就是要第一个出场
2844: albus就是要第一个出场 链接 分析: 和HDU3949差不多互逆,这里需要加上相同的数. 结论:所有数任意异或,构成的数出现一样的次数,次数为$2^{n-cnt}$,cnt为线性基的大 ...
- P1107 最大整数
P1107 最大整数 题目描述 设有n个正整数 (n<=20), 将它们连接成一排, 组成一个最大的多位整数. 例如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 3433 ...
- Gradle 设置本地meaven
repositories { maven { url uri("F:\\meaven")} }
- scidb
貌似是给科学家用的数据库,暂不研究