[bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)
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
QS
CC
QS
CW
QS
QM
Sample Output
HINT
N,Q < =10^5 , C < =10^5
数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时
刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。
Solution
水题
用主席树做一做就好
#include <stdio.h>
#include <string.h>
#define RG register
#define N 100010
#define dmax(a,b) ((a)>(b)?(a):(b))
template<class Type> inline void R(RG Type &x) {
RG int c=getchar();for(;c<48||c>57;c=getchar());
for(x=0;c>47&&c<58;x=(x<<1)+(x<<3)+c-48,c=getchar()); }
bool vis[N];int n,q,w[N],c[N],tim,fa[N],dep[N],sz[N],lef[N],top[N],hso[N],tot,root[N];
struct Pt {
int v; Pt *nt; }*fi[N],me[N<<1],*tp=me;
struct Ch {
int ls,rs,mx,su; }tr[N*40];
inline void link(RG int x,RG int y) {
*++tp=(Pt){y,fi[x]},fi[x]=tp;
*++tp=(Pt){x,fi[y]},fi[y]=tp; }
void dfsi(RG int x){
vis[x]=sz[x]=1;
for(RG Pt *it=fi[x];it;it=it->nt)
if(!vis[it->v])
dep[it->v]=dep[x]+1,
fa[it->v]=x,
dfsi(it->v),
sz[x]+=sz[it->v],
hso[x]=sz[it->v]>sz[hso[x]]?it->v:hso[x];
}
void dfsm(RG int x){
vis[x]=0;
top[x]=x==hso[fa[x]]?top[fa[x]]:x;
lef[x]=++tim;
if(hso[x]){
dfsm(hso[x]);
for(RG Pt *it=fi[x];it;it=it->nt)
if(vis[it->v])
dfsm(it->v);
}
}
inline int lca(RG int x,RG int y){
while(top[x]^top[y])
dep[top[x]]>dep[top[y]]?
x=fa[top[x]]:
y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
inline void Pu(RG int pr) {
tr[pr].mx=dmax(tr[tr[pr].ls].mx,tr[tr[pr].rs].mx);
tr[pr].su=tr[tr[pr].ls].su+tr[tr[pr].rs].su; }
void modify(RG int &pr,RG int x,RG int y,RG int po,RG int nu){
if(!pr)pr=++tot;
if(!(x^y)) {tr[pr].mx=tr[pr].su=nu; return; }
RG int mid=x+y>>1;
if(po<=mid)modify(tr[pr].ls,x,mid,po,nu);
else modify(tr[pr].rs,mid+1,y,po,nu);
Pu(pr);
}
int qmx(RG int pr,RG int x,RG int y,RG int u,RG int v){
if(!pr)return 0;
if(x==u&&y==v)return tr[pr].mx;
RG int mid=x+y>>1;
if(v<=mid)return qmx(tr[pr].ls,x,mid,u,v);
if(u>mid)return qmx(tr[pr].rs,mid+1,y,u,v);
return dmax(qmx(tr[pr].ls,x,mid,u,mid),qmx(tr[pr].rs,mid+1,y,mid+1,v));
}
int qsm(RG int pr,RG int x,RG int y,RG int u,RG int v){
if(!pr)return 0;
if(x==u&&y==v)return tr[pr].su;
RG int mid=x+y>>1;
if(v<=mid)return qsm(tr[pr].ls,x,mid,u,v);
if(u>mid)return qsm(tr[pr].rs,mid+1,y,u,v);
return qsm(tr[pr].ls,x,mid,u,mid)+qsm(tr[pr].rs,mid+1,y,mid+1,v);
}
inline int solvem(RG int col,RG int x,RG int f){
int re=0;
while(top[x]^top[f])
re=dmax(re,qmx(root[col],1,n,lef[top[x]],lef[x])),x=fa[top[x]];
re=dmax(re,qmx(root[col],1,n,lef[f],lef[x]));
return re;
}
inline int solves(int col,int x,int f){
int re=0;
while(top[x]^top[f])
re+=qsm(root[col],1,n,lef[top[x]],lef[x]),x=fa[top[x]];
re+=qsm(root[col],1,n,lef[f],lef[x]);
return re;
}
int main(){
RG char si[10];R(n),R(q);
for(RG int i=1;i<=n;i++)R(w[i]),R(c[i]);
for(RG int i=1,x,y;i<n;i++)R(x),R(y),link(x,y);
dfsi(1),dfsm(1);
for(RG int i=1;i<=n;i++)modify(root[c[i]],1,n,lef[i],w[i]);
for(int x,y,t,tmp;q;q--){
scanf("%s",si),R(x),R(y);
if(si[0]=='C'&&si[1]=='C')
modify(root[c[x]],1,n,lef[x],0),
c[x]=y,
modify(root[c[x]],1,n,lef[x],w[x]);
if(si[0]=='C'&&si[1]=='W')
modify(root[c[x]],1,n,lef[x],y),w[x]=y;
if(si[0]=='Q'&&si[1]=='S')
t=lca(x,y),tmp=solves(c[x],x,t)+solves(c[x],y,t),c[x]==c[t]?tmp-=w[t]:1,printf("%d\n",tmp);
if(si[0]=='Q'&&si[1]=='M')
t=lca(x,y),printf("%d\n",dmax(solvem(c[x],x,t),solvem(c[x],y,t)));
}
return 0;
}
[bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)的更多相关文章
- BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树
题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...
- BZOJ3531 [Sdoi2014]旅行 树链剖分 线段树
原文链接:http://www.cnblogs.com/zhouzhendong/p/8080189.html 题目传送门 - BZOJ3531 题意概括 一棵树,n个节点,每一个节点两个值,一个颜色 ...
- BZOJ3531[Sdoi2014]旅行——树链剖分+线段树
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...
- BZOJ3531:[SDOI2014]旅行(树链剖分)
Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...
- 2018.07.24 bzoj3531: [Sdoi2014]旅行(树链剖分+动态开点)
传送门 树链剖分. 如何维护? 如果颜色少直接每种颜色一颗线段树走人. 但这题颜色数量不大于1e5" role="presentation" style="po ...
- 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
离线后以宗教为第一关键字,操作时间为第二关键字排序. <法一>块状树,线下ac,线上tle…… #include<cstdio> #include<cmath> # ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- Bzoj3531: [Sdoi2014]旅行
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1698 Solved: 758 Description S国有N个城市,编号从1到N.城市间用N-1 ...
- bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...
随机推荐
- AngularJs调用NET MVC 控制器中的函数进行后台操作
题目中提到的控制器指的是.NET MVC的控制器,不是angularjs的控制器. 首先看主页面的代码: <!DOCTYPE html> <html> <head> ...
- ASP.NET MVC+Bootstrap个人博客之修复UEditor编辑时Bug(四)
我的个人博客站在使用百度富文本编辑器UEditor修改文章时,遇到了一些问题,(不知是bug,还是我没有配置好).但总算找到了解决方法,在此记录下来. 遇到的问题: 正常来讲,进入文章修改页,只需将U ...
- Android开发学习——ButterKnife使用
为了码代码的效率,我们有了ButterKnife;其基本使用如下步骤: 1.在Android Studio的Setting中,下载plugin 2.在整个Project的build.gradle中添加 ...
- 工作记录 angular页面操作 MD5加密
今天只是做页面,基于angularjs,有美工做的图打底,确实好用 密码保存,用到了C# MD5加密: https://www.cnblogs.com/healer007/p/5062189.html
- JDK集合框架--综述
接下来的几篇博客总结一下对jdk中常用集合类知识,本篇博客先整体性地介绍一下集合及其主要的api: 从整体上来说,集合分两大类collection和map: 首先来看看Collection: c ...
- @GetMapping和@PostMapping 和@RequestMapping区别
@GetMapping 用于将HTTP GET请求映射到特定处理程序方法的注释. 具体来说,@GetMapping是一个作为快捷方式的组合注释@RequestMapping(method = Requ ...
- com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "FileSize"
请求阿里云的OSS接口图片信息,返回json格式的数据,通过ObjectMapper将json转为Image对象时候报错转换失败 将json转对象的代码: String jsonStr = " ...
- R in action读书笔记(4)-第六章:基本图形(下)
6.3直方图 hist() 其中的x是一个由数据值组成的数值向量.参数freq=FALSE表示根据概率密度而不是频数绘制图形.参数breaks用于控制组的数量.在定义直方图中的单元时,默认将生成等距切 ...
- 最全的Java面试宝典
一. 前言部分 从享受生活的角度上来说:“程序员并不是一种最好的职业,我认为两种人可以做程序员,第一,你不做程序员,你就没有什么工作可做,或者说是即使有可以做的工作但是你非常不愿意去做:第二,你非常痴 ...
- 玩转CPU运行曲线
Leaf 是不是从来没有想过看看cpu运行曲线啊骚年?顶多也就仅仅是看看cpu利用率,吓自己一跳后感觉关闭几个不该打开的程序~ 然而问题来了,微软公司要让你绘制cpu运行曲线啊!!不仅是固定的直线,还 ...