对每一个宗教建一棵线段树,然后树剖搞搞

#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]旅行的更多相关文章

  1. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  2. 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树

    [BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...

  3. bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 876  Solved: 446[Submit][Status][ ...

  4. [SDOI2014]旅行

    洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...

  5. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  6. [luogu P3313] [SDOI2014]旅行

    [luogu P3313] [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神 ...

  7. 洛谷 P3313 [SDOI2014]旅行 解题报告

    P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...

  8. bzoj 3531 [Sdoi2014]旅行 (树剖+线段树 动态开点)

    3531: [Sdoi2014]旅行 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2984  Solved: 1312[Submit][Status ...

  9. P3313 [SDOI2014]旅行

    P3313 [SDOI2014]旅行 树链剖分+动态线段树(并不是lct) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...

随机推荐

  1. 关于bootstrap table的server分页

    首先是bootstrap初始化的表格参数: // 初始化Table oTableInit.Init = function() { $('#booksTable').bootstrapTable({ u ...

  2. 学好Mac常用命令,助力iOS开发

    原文出处: Jack_lin(@Jack_Lin_IOS ) 厚重·技术 序言 在iOS开发的过程中,更多地注重iOS开发的效率,熟练使用Mac终端操作的常用命令,可以让你更好的游刃于iOS繁重的开发 ...

  3. Suricata的规则解读(默认和自定义)

    不多说,直接上干货! 见suricata官网 https://suricata.readthedocs.io/en/latest/rules/index.html 一.Suricata的规则所放位置 ...

  4. [转]IntelliJ IDEA 自定义方法注解模板

    IntelliJ IDEA 自定义方法注解模板 置顶2017年08月02日 18:04:36 阅读数:32592 最近没啥事开始正式用Eclipse 转入 idea工具阵营,毕竟有70%的开发者在使用 ...

  5. 滚动字幕Marquee

    基本语法  <marquee>滚动文字 </marquee> 文字移动属性的设置  方向 <direction=#> #=left, right,up,down 方 ...

  6. PHP获取时间总结

    查询前一年时间戳 mktime(0,0,0,date('m'),date('d'),date('Y')-1); strtotime('-12 month'); 查询前6个月时间戳 mktime(0,0 ...

  7. phpstorm中快速添加函数注释

    Preferences 或 command+,快捷键 Live Templates - PHP 下方 - 新建模板 ,Abbreviation 命名随便写,点击Edit Variables配置变量信息 ...

  8. windows.old文件删除

    在安装完新系统后,会发现C盘下有个windows.old文件夹,大约有个10多G,里面都是对之前系统的一些备份,用于对之前系统恢复时使用,一般一个月后会自动清理,若觉得不会再对系统进行老版本恢复时,又 ...

  9. IOS的水滴文件效果

    @implementation ViewController - (void)viewDidLoad{ [super viewDidLoad]; NSDictionary *dict = [NSDic ...

  10. 使用Eclipse进行PHP的服务器端调试

    最近工作需要对PHP的服务器端代码进行远程调试,涉及到Eclipse里环境的设置.在网上找了很多资料,大多不全,或者缺少配图,于是把自己做的过程中遇到的问题记录了下来,希望对需要的朋友们有所帮助. 首 ...