Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1698  Solved: 758

Description

S国有N个城市,编号从1到N。城市间用N-1条双向道路连接,满足
从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。为了方便,我们用不同的正整数代表各种宗教,  S国的居民常常旅行。旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。
    在S国的历史上常会发生以下几种事件:
”CC x c”:城市x的居民全体改信了c教;
”CW x w”:城市x的评级调整为w;
”QS x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级总和;
”QM x y”:一位旅行者从城市x出发,到城市y,并记下了途中留宿过
的城市的评级最大值。
    由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。    为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。

Input

输入的第一行包含整数N,Q依次表示城市数和事件数。
    接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的
评级和信仰。
    接下来N-1行每行两个整数x,y表示一条双向道路。
    接下来Q行,每行一个操作,格式如上所述。

Output

对每个QS和QM事件,输出一行,表示旅行者记下的数字。

Sample Input

5 6
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4

Sample Output

8
9
11
3

HINT

N,Q < =10^5    , C < =10^5

数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时

刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。

Source

Round 1 Day 1

树链剖分+线段树森林

时间限制还是很良心的

不考虑颜色问题的话,这就是个树点权求改,链权求和的树剖裸题。

加上颜色问题的话……看到题目的时间限制和空间限制,似乎可以放心搞事情。

建C棵线段树,每棵线段树维护一种颜色的结点信息,每次在对应颜色的线段树上统计答案。

如果用root*2 root*2+1的写法存子树,空间妥妥炸,那么改成指针式就好。由于操作数的限制,实际上每棵线段树最终只会建出来一小部分。

极限状况下线段树最多需要添加log(10^5)/log(2)  * n == 160w个结点

 #include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct edge{int v,nxt;}e[mxn<<];
int hd[mxn],mct=;
void add_edge(int u,int v){e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;}
int n,Q;
struct node{
int top,fa;
int w,e;
int size,son;
}t[mxn];
int dep[mxn];
struct sgt{
int lc,rc;
int mx,smm;
}st[mxn<<];
int sz=;//sct=0;
int rt[mxn];
int w[mxn],c[mxn];
void DFS1(int u,int fa){
t[u].fa=fa;
t[u].size=;
dep[u]=dep[fa]+;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa)continue;
DFS1(v,u);
t[u].size+=t[v].size;
if(t[v].size>t[t[u].son].size)
t[u].son=v;
}
return;
}
void DFS2(int u,int top){
t[u].w=++sz;
t[u].top=top;
if(t[u].son)DFS2(t[u].son,top);
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v!=t[u].son && v!=t[u].fa)DFS2(v,v);
}
t[u].e=sz;
return;
}
void pushup(int rt){
int lc=st[rt].lc;int rc=st[rt].rc;
st[rt].mx=max(st[lc].mx,st[rc].mx);
st[rt].smm=st[lc].smm+st[rc].smm;
return;
}
void update(int p,int v,int l,int r,int &rt){
if(!rt){rt=++sz;}
if(l==r){st[rt].mx=st[rt].smm=v;return;}
int mid=(l+r)>>;
if(p<=mid)update(p,v,l,mid,st[rt].lc);
else update(p,v,mid+,r,st[rt].rc);
pushup(rt);
return;
}
int qsum(int L,int R,int l,int r,int rt){
// printf("%d %d %d %d %d :%d\n",L,R,l,r,rt,st[rt].smm);
if(!rt)return ;
if(L<=l && r<=R){return st[rt].smm;}
int mid=(l+r)>>;
int res=;
if(L<=mid)res+=qsum(L,R,l,mid,st[rt].lc);
if(R>mid)res+=qsum(L,R,mid+,r,st[rt].rc);
return res;
}
int qmax(int L,int R,int l,int r,int rt){
if(!rt)return -1e9;
if(L<=l && r<=R){return st[rt].mx;}
int mid=(l+r)>>;
int res=-1e9;
if(L<=mid)res=max(res,qmax(L,R,l,mid,st[rt].lc));
if(R>mid)res=max(res,qmax(L,R,mid+,r,st[rt].rc));
return res;
}
int asksum(int color,int x,int y){
int res=;
while(t[x].top!=t[y].top){
if(dep[t[x].top]<dep[t[y].top])swap(x,y);
res+=qsum(t[t[x].top].w,t[x].w,,n,rt[color]);
x=t[t[x].top].fa;
}
if(dep[x]>dep[y])swap(x,y);
res+=qsum(t[x].w,t[y].w,,n,rt[color]);
return res;
}
int askmax(int color,int x,int y){
int res=-1e9;
while(t[x].top!=t[y].top){
if(dep[t[x].top]<dep[t[y].top])swap(x,y);
res=max(res,qmax(t[t[x].top].w,t[x].w,,n,rt[color]));
x=t[t[x].top].fa;
}
if(dep[x]>dep[y])swap(x,y);
res=max(res,qmax(t[x].w,t[y].w,,n,rt[color]));
return res;
}
int main()
{
int i,j,u,v;
n=read();Q=read();
for(i=;i<=n;i++){w[i]=read();c[i]=read();}
for(i=;i<n;i++){
u=read();v=read();
add_edge(u,v);
add_edge(v,u);
}
DFS1(n/,);
DFS2(n/,n/);
for(i=;i<=n;i++){
update(t[i].w,w[i],,n,rt[c[i]]);
}
char op[];int x,y;
while(Q--){
scanf("%s",op);x=read();y=read();
if(op[]=='C'){
if(op[]=='C'){
update(t[x].w,,,n,rt[c[x]]);
c[x]=y;
update(t[x].w,w[x],,n,rt[c[x]]);
}
else{
update(t[x].w,y,,n,rt[c[x]]);
w[x]=y;
}
}
else{
if(op[]=='S'){
printf("%d\n",asksum(c[x],x,y));
}
else{
printf("%d\n",askmax(c[x],x,y));
}
}
}
return ;
}

Bzoj3531: [Sdoi2014]旅行的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Dynamics CRM 2016 的新特性

    新版本CRM (2016 with update 0.1) 发布已有几个月了,总结一下新特性,从几个方面来看: 1. 针对整合功能的新特性 (1) 增加了CRM App for Outlook. 这个 ...

  2. codevs2693 上学路线(施工)

    难度等级:黄金 2693 上学路线(施工) 题目描述 Description 问题描述 你所在的城市街道好像一个棋盘,有a条南北方向的街道和b条东西方向的街道. 南北方向a条街道从西到东依次编号为1到 ...

  3. ASP.NET MVC 教程-MVC简介

    ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器脚本创建网页和网站的开发框架. ASP.NET 支持三种不同的开发模式:Web Pages(Web 页面).MVC(Mode ...

  4. 无法连接windows虚拟机oracle的解决办法

    在mac机上玩基于oracle db的开发真心不容易,oracle公司死活不出oracle express edition for mac OS,曾经发布过的oracle 10 for mac下载地址 ...

  5. RMQ(ST算法)

    RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列a,回答若干询问RMQ(A,i,j)(i, j<=n),返回数列a中下标在i ...

  6. opencv4-highgui之视频的输入和输出以及滚动条

    这是<opencv2.4.9tutorial.pdf>的highgui的三个例子.通过简短的介绍来实现不同函数的理解,省去一些不需要说的东西. 一.增加滑动条 这是opencv中为数不多的 ...

  7. Hashtable Dictionary List 谁效率更高

    一 前言 很少接触HashTable晚上回来简单看了看,然后做一些增加和移除的操作,就想和List 与 Dictionary比较下存数据与取数据的差距,然后便有了如下的一此测试, 当然我测的方法可能不 ...

  8. 让 Generator 自启动

    文章同步自个人博客:http://www.52cik.com/2016/07/11/generator-co.html 此前只是简单使用而没有真正的去研究 Generator,这次要好好折腾下这货. ...

  9. CodeIgniter框架入门教程——第三课 URL及ajax

    本文转载自:http://www.softeng.cn/?p=74 这节课讲一下CI框架的路由规则,以及如何在CI框架下实现ajax功能. 首先,先介绍CI框架的路由规则,因为CI框架是在PHP的基础 ...

  10. grootJsAPI文档

    groot.view(name,factory) 用于创建一个modelView对象与指令gt-view对应 参数 用途 name 创建的modelView的名称,用groot.vms[name]可以 ...