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) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...
随机推荐
- org.codehaus.jettison.json.JSONObject使用方法
public static void main(String[] args) { System.out.println("测试开始"); File file = new File( ...
- 机器学习概念之特征选择(Feature selection)之RFormula算法介绍
不多说,直接上干货! RFormula算法介绍: RFormula通过R模型公式来选择列.支持R操作中的部分操作,包括‘~’, ‘.’, ‘:’, ‘+’以及‘-‘,基本操作如下: 1. ~分隔目标和 ...
- input标签属性
很多时候,我们都用到了很多标签实现输入功能,所以在这里梳理一下. 1.建立一个文本框 <input type="text" name="userName" ...
- Dapper系列之三:Dapper的事务修改与删除
Dapepr的Update和Delete Dapper入门Dapper查询 上两篇文章我们介绍Dapper中添加和查询.本篇文章我们继续讲解修改和删除....如果本篇文章看不懂,请看阅读上两篇Dapp ...
- iphone x 高度:100%; 兼容设置
问题: iphone x 会遇到页面设置 height:100%;之后但是底部还有一定的高度没有覆盖 解决方法: 1.让客户端设置webview的高度为100%; 2.html代码里面添加 viewp ...
- C++模板类头文件和实现文件分离
http://www.cnblogs.com/lvdongjie/p/4288373.html 如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer ...
- laravel学习笔记(一)
laravel 简述 优点:优雅.简洁.工程化(项目架构,协同开发) 版本:2011 June 1.0 ,LTS(long time) ,laravel 5.4 功能:队列.搜索.数据库搜索.定时脚本 ...
- 字符串逆序-c语言
给定一个含有n个元素的字符串,实现逆序. 这是个很基础的问题,实现方式也是很常见的c语言思路.虽然简单,但是仍然记录下来. [期望] 比如char str[] = "abcdefg" ...
- MySQL数据表查询操作
准语法结构:编写DQL时一定要严格按照此语法的顺序来实现!/* SELECT [ALL | DISTINCT] ALL表示查询出所有的内容 DISTINCT 去重 {* | 表名.* | 表名.字段名 ...
- C3P0连接池工具类实现步骤及方法
C3P0连接池的工具类 使用C3P0获得连接对象连接池有一个规范接口 javax.sal.DataSourse 接口定义了一个从连接池中获得连接的方法getConnection(); 步骤导入jar包 ...