题目传送门

题目大意:给定一棵无根树,每个节点有自己的类别和权值,现在给定两个类别相同的点,叫你求这2点路径上同类别节点的权值和/最大权值。

节点类别与权值会改变。

解题思路:考虑对每一个类别开一棵线段树,动态开点,可以写指针,也可以开数组写链表,然后剩下的就是树剖的东西了。我写的是指针,跑的略慢一些,时间效率为\( O(q \log^{2} n) \).

代码由于是在自家的mac上码的,所以和以前风格不大一样。

 #include <stdio.h>
#define MN 100005
inline void swp(int &a,int &b){a ^= b ^= a ^= b;}
inline int max(int a,int b){return a > b ? a : b;}
inline int in(){
int x = ,f = ; char ch = getchar();
while (ch < '' || ch > '') f = ch=='-' ? - : , ch = getchar();
while (ch >= '' && ch <= '' ) x = (x<<) + (x<<) + ch - '',ch = getchar();
return x*f;
}
struct segment_tree{
segment_tree *ls , *rs;
int sum,ma;
void combine(){
sum = ma = ;
if (ls != NULL){
sum += ls -> sum;
ma = max( ma , ls -> ma );
}if (rs != NULL){
sum += rs -> sum;
ma = max( ma , rs -> ma );
}
}
segment_tree (int sum=,int ma=):sum(sum),ma(ma){ls = rs = NULL;}
}*ST[MN];
#define S_T segment_tree
int to[MN<<],nxt[MN<<],cnt,head[MN];
int n,q,top[MN],siz[MN],son[MN],val[MN],belief[MN],fa[MN],dep[MN],pos[MN],dfsn;
inline void ins(int x,int y){to[++cnt] = y , nxt[cnt] = head[x] , head[x] = cnt;}
inline void insw(int x,int y){ins(x,y); ins(y,x);}
inline void dfs1(int u,int f,int d){
siz[u] = ; dep[u] = d; fa[u] = f;
for (register int i = head[u]; i; i = nxt[i])
if (to[i] != f) {
dfs1(to[i],u,d+); siz[u] += siz[to[i]];
if (siz[son[u]] < siz[to[i]]) son[u] = to[i];
}
}
inline void dfs2(int u,int tp){
top[u] = tp; pos[u] = (++dfsn); if (son[u]) dfs2(son[u],tp);
for (register int i = head[u]; i; i = nxt[i])
if (to[i] != fa[u] && to[i] != son[u]) dfs2(to[i],to[i]);
}
#define mid (l+r>>1)
inline void insert(S_T* &x,int l,int r,int pos,int val){
if (x == NULL) x = new S_T;
if (l == r){x -> sum = x -> ma = val; return;}
if (pos <= mid) insert(x -> ls,l,mid,pos,val);
else insert(x -> rs,mid+,r,pos,val);x->combine();
}
inline void Delete(S_T* &x,int l,int r,int pos){
if (l==r){delete x; x = NULL; return; }
if (pos<=mid) Delete(x -> ls,l,mid,pos);
else Delete(x -> rs,mid+,r,pos);
if (x -> ls == NULL && x -> rs == NULL){delete x; x = NULL; return; }
else x -> combine();
}
inline int QM(S_T* &x,int l,int r,int a,int b){
if (x == NULL) return ;
if (l == a && r == b) return x -> ma;
if (b<=mid) return QM(x -> ls,l,mid,a,b);
if (a>mid) return QM(x -> rs,mid+,r,a,b);
return max(QM(x -> ls,l,mid,a,mid),QM(x -> rs,mid+,r,mid+,b));
}
inline int QS(S_T* &x,int l,int r,int a,int b){
if (x == NULL) return ;
if (l == a && r == b) return x -> sum;
if (b<=mid) return QS(x -> ls,l,mid,a,b);
if (a>mid) return QS(x -> rs,mid+,r,a,b);
return QS(x -> ls,l,mid,a,mid)+QS(x -> rs,mid+,r,mid+,b);
}
inline int qm(int belief,int x,int y){
register int res = ;
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swp(x,y);
res = max(res,QM(ST[belief],,n,pos[top[x]],pos[x]));
x = fa[top[x]];
}if (dep[x] > dep[y]) swp(x,y);res = max(res,QM(ST[belief],,n,pos[x],pos[y]));
return res;
}
inline int qs(int belief,int x,int y){
register int res = ;
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swp(x,y);
res += QS(ST[belief],,n,pos[top[x]],pos[x]);
x = fa[top[x]];
}if (dep[x] > dep[y]) swp(x,y);res += QS(ST[belief],,n,pos[x],pos[y]);
return res;
}
void init(){
n = in() , q = in();
for (int i = ; i <= n; ++i) val[i] = in() , belief[i] = in();
for (register int i = ; i < n; ++i) insw(in(),in());
dfs1(,,);dfs2(,);
for (register int i = ; i <= n; ++i)
insert(ST[belief[i]],,n,pos[i],val[i]);
}
void solve(){
while(q--){
register char op[]; scanf("%s",op);
register int x=in(),y=in();
if (op[] == 'C'){
if (op[] == 'C'){
Delete(ST[belief[x]],,n,pos[x]);
insert(ST[belief[x] = y],,n,pos[x],val[x]);
}else insert(ST[belief[x]],,n,pos[x],val[x]=y);
}else{
if (op[] == 'M') printf("%d\n",qm(belief[x],x,y));
else printf("%d\n",qs(belief[x],x,y));
}
}
}
int main(){ init(); solve();}

【BZOJ3531】【SDOI2014】旅行的更多相关文章

  1. Bzoj3531: [Sdoi2014]旅行

    Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1698  Solved: 758 Description S国有N个城市,编号从1到N.城市间用N-1 ...

  2. BZOJ3531 [Sdoi2014]旅行 树链剖分 线段树

    原文链接:http://www.cnblogs.com/zhouzhendong/p/8080189.html 题目传送门 - BZOJ3531 题意概括 一棵树,n个节点,每一个节点两个值,一个颜色 ...

  3. BZOJ3531[Sdoi2014]旅行——树链剖分+线段树

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...

  4. BZOJ3531:[SDOI2014]旅行(树链剖分)

    Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...

  5. BZOJ3531 [Sdoi2014]旅行 【树剖 + 线段树】

    题目 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们用 ...

  6. [bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)

    Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. ...

  7. 2018.07.24 bzoj3531: [Sdoi2014]旅行(树链剖分+动态开点)

    传送门 树链剖分. 如何维护? 如果颜色少直接每种颜色一颗线段树走人. 但这题颜色数量不大于1e5" role="presentation" style="po ...

  8. 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行

    离线后以宗教为第一关键字,操作时间为第二关键字排序. <法一>块状树,线下ac,线上tle…… #include<cstdio> #include<cmath> # ...

  9. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

  10. bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)

    感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...

随机推荐

  1. java实现找一个数范围内所有的一

    一.题目内容 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数.要求:写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数.例如 f(12)  = 5. ...

  2. Linux学习--线程控制

    关于线程控制,主要就是几个模块,我们一个一个消灭.消化: 一.线程创建: 1.先来看看在Linux环境下的线程创建函数: 分析:意思很明显: 1.函数名是 pthread_create  : 2.功能 ...

  3. IOS UITextView自适应高度

    LOFTER app需要实现了一个类似iPhone短信输入框的功能,它的功能其实蛮简单,就是:[UITextView的高度随着内容高度的变化而变化].实现思路应该是: 在UITextView的text ...

  4. 老板怎么办,我们网站遭到DDoS攻击又挂了?

    相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...

  5. 微信小程序轮播图

    swiper标签 <!--index.wxml--> <swiper class="swiper" indicator-dots="true" ...

  6. zookeeper 入门系列-理论基础 – zab 协议

    上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...

  7. 彻底搞懂shell的高级I/O重定向

    本文目录: 1.1 文件描述符(file description,fd) 1.2 文件描述符的复制 1.3 重定向顺序很重要:">file 2>&1"和&quo ...

  8. js判断语句关于true和false后面跟数字或字符串的问题

    我经常在代码中看到很长串判断,看到就头疼,简单的整理一下. 比如:(client.top>=0&&client.left>=0&&client.bottom ...

  9. 使用 HttpClient3.1 和 HtmlParser2.1 开发Crawler

    https://www.ibm.com/developerworks/cn/opensource/os-cn-crawler/

  10. angular2 学习笔记 ( translate, i18n 翻译 )

    更新 : 2017-06-17 <h1 i18n="site header|An introduction header for this sample">Hello ...