luogu3313 [SDOI2014]旅行
对每一个宗教建一棵线段树,然后树剖搞搞
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, w[100005], c[100005], uu, vv, hea[100005], cnt, dep[100005];
int fa[100005], top[100005], idx[100005], qaq, siz[100005], son[100005];
int rot[100005], orz, zdz[5000005], sum[5000005], lson[5000005];
int rson[5000005];
char ss[15];
struct Edge{
int too, nxt, val;
}edge[200005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
void dfs1(int x, int f){
fa[x] = f;
siz[x] = 1;
dep[x] = dep[f] + 1;
int maxSon=-1;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f){
dfs1(t, x);
siz[x] += siz[t];
if(maxSon<siz[t]) maxSon = siz[t], son[x] = t;
}
}
}
void dfs2(int x, int topf){
top[x] = topf;
idx[x] = ++qaq;
if(!son[x]) return ;
dfs2(son[x], topf);
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=fa[x] && t!=son[x])
dfs2(t, t);
}
}
void pushUp(int o){
sum[o] = sum[lson[o]] + sum[rson[o]];
zdz[o] = max(zdz[lson[o]], zdz[rson[o]]);
}
void insert(int &o, int l, int r, int x, int w){
if(!o) o = ++orz;
if(l==r) sum[o] = zdz[o] = w;
else{
int mid=(l+r)>>1;
if(x<=mid) insert(lson[o], l, mid, x, w);
if(mid<x) insert(rson[o], mid+1, r, x, w);
pushUp(o);
}
}
void clr(int &o){
lson[o] = rson[o] = sum[o] = zdz[o] = 0;
o = 0;
}
void shanchu(int &o, int l, int r, int x){
if(l==r) clr(o);
else{
int mid=(l+r)>>1;
if(x<=mid) shanchu(lson[o], l, mid, x);
if(mid<x) shanchu(rson[o], mid+1, r, x);
pushUp(o);
if(lson[o]+rson[o]==0) clr(o);
}
}
int querySGTSum(int o, int l, int r, int x, int y){
if(!o) return 0;
if(l>=x && r<=y) return sum[o];
else{
int mid=(l+r)>>1;
int ans=0;
if(x<=mid) ans += querySGTSum(lson[o], l, mid, x, y);
if(mid<y) ans += querySGTSum(rson[o], mid+1, r, x, y);
return ans;
}
}
int querySGTMax(int o, int l, int r, int x, int y){
if(!o) return 0;
if(l>=x && r<=y) return zdz[o];
else{
int mid=(l+r)>>1;
int ans=0;
if(x<=mid) ans = max(ans, querySGTMax(lson[o], l, mid, x, y));
if(mid<y) ans = max(ans, querySGTMax(rson[o], mid+1, r, x, y));
return ans;
}
}
int querySum(int uu, int vv){
int bel=c[uu], ans=0;
while(top[uu]!=top[vv]){
if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv);
ans += querySGTSum(rot[bel], 1, n, idx[top[uu]], idx[uu]);
uu = fa[top[uu]];
}
if(dep[uu]>dep[vv]) swap(uu, vv);
ans += querySGTSum(rot[bel], 1, n, idx[uu], idx[vv]);
return ans;
}
int queryMax(int uu, int vv){
int bel=c[uu], ans=0;
while(top[uu]!=top[vv]){
if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv);
ans =max(ans, querySGTMax(rot[bel], 1, n, idx[top[uu]], idx[uu]));
uu = fa[top[uu]];
}
if(dep[uu]>dep[vv]) swap(uu, vv);
ans = max(ans, querySGTMax(rot[bel], 1, n, idx[uu], idx[vv]));
return ans;
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++) scanf("%d %d", &w[i], &c[i]);
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
dep[1] = 1;
dfs1(1, 0);
dfs2(1, 1);
for(int i=1; i<=n; i++)
insert(rot[c[i]], 1, n, idx[i], w[i]);
while(m--){
scanf("%s %d %d", ss, &uu, &vv);
if(ss[0]=='C' && ss[1]=='C'){
shanchu(rot[c[uu]], 1, n, idx[uu]);
c[uu] = vv;
insert(rot[c[uu]], 1, n, idx[uu], w[uu]);
}
if(ss[0]=='C' && ss[1]=='W'){
w[uu] = vv;
insert(rot[c[uu]], 1, n, idx[uu], w[uu]);
}
if(ss[0]=='Q' && ss[1]=='S')
printf("%d\n", querySum(uu, vv));
if(ss[0]=='Q' && ss[1]=='M')
printf("%d\n", queryMax(uu, vv));
}
return 0;
}
luogu3313 [SDOI2014]旅行的更多相关文章
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- 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) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...
随机推荐
- Python: How to iterate list in reverse order
#1 for index, val in enumerate(reversed(list)): print len(list) - index - 1, val #2 def reverse_enum ...
- hash 【模板】
hash 功能: hash一般用于快速判断两个或多个字符串是否匹配. 实现 : 想一想,如果比较两个数子的话是很方便的很快,那么我们把整个字符串看成一个大数. 它是base进制的len位数.但 ...
- JUnit的好搭档-Hamcrest
一.Hamcrest简介 Hamcrest是一个用于编写匹配器(matcher)对象的框架,允许以声明方式定义“匹配(match)”规则.它可以与JUnit框架配合使用,使断言可读更高,更加灵活(例如 ...
- 前端的百度地图的api的使用
1.打开百度地图官方api网页 http://lbsyun.baidu.com/ 2.点击开发文档 3.选择对应的api 4.点击DEMO详情 5.得到源码复制到你的代码中 <!DOCTYPE ...
- hdu4003/蓝桥杯 金属采集
思路: 树形dp + 分组背包dp. 参考https://www.cnblogs.com/kuangbin/archive/2012/08/29/2661928.html 实现: #include & ...
- QQ面板拖拽(慕课网DOM事件探秘)(上)
QQ面板拖拽,效果如图 JavaScript代码如下: function getByClass(clsName, parent) { var oParent = parent ? document.g ...
- DHCP server工作原理
1.CLIENT首先发出广播的DHCPDISCOVER报文,广播的目的是让DHCP SERVER能够收到这个请求报文.在这个报文中,CLIENT可以在"选项"字段中加入" ...
- 计数器:counter
组成:2属性,1方法 属性1: counter-reset 命名 属性2: counter-increment 启动/自增 方法 : counter()/counters() 调用方法 1.计数器 命 ...
- 深入Docker 存储驱动 (转)
参考: http://static.dockerone.com/ppt/filedriver.html#28
- cyclic swapping algorithm
原文见:https://leetcode.com/problems/couples-holding-hands/discuss/113362/JavaC%2B%2B-O(N)-solution-usi ...