[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 ...
随机推荐
- java 调用动态库打包sdk
java连接c++动态库并生成jar包提供给别人调用 1.需要将java通过jni生成头文件,并导入到c++项目并对c++进行jni方法继承 在项目的src目录执行,否则会提示 错误:找不到符号 ja ...
- [Usaco2017 Open]Modern Art 2
Description Having become bored with standard 2-dimensional artwork (and also frustrated at others c ...
- 利用autotools工具制作从源代码安装的软件 分类: linux 2014-06-02 23:27 340人阅读 评论(0) 收藏
编写程序(helloworld.c)并将其放到一个单独目录. helloworld.c: #include<stdio.h> int main() { printf("hello ...
- 201 Bitwise AND of Numbers Range 数字范围按位与
给定范围 [m,n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含m, n两端点).例如,给定范围 [5,7],您应该返回 4. 详见 ...
- URAL1326. Bottle Taps(状压)
1326 用队列优化的 不知道为什么一直WA 传统直白的 状压 写了超时 O((1<<n)*m*n) 之后想了可以把n省去 预处理一下方案 #include <iostream&g ...
- [ USACO 2013 OPEN ] Photo
\(\\\) Description 有一个长度为 \(n\) 的奶牛队列,奶牛颜色为黑或白. 现给出 \(m\) 个区间 \([L_i,R_i]\) ,要求:每个区间里 有且只有一只黑牛 . 问满足 ...
- lua使用lfs.dll库进行文件操作
在项目开发中,为了提高开发效率往往需要开发一些辅助工具.最近在公司用lua帮拓展了一个资源扫描的工具,这个工具的功能就是从原始demo下指定目标资源文件,对该文件进行读取并筛选过滤一遍然后拷贝到最终d ...
- thinkphp查询,3.X 5.0 亲试可行
[php] view plain copy print? 一.介绍 ThinkPHP内置了非常灵活的查询方法,可以快速的进行数据查询操作,查询条件可以用于读取.更新和删除等操作,主要涉及到wher ...
- shiro 通过jdbc连接数据库
本文介绍shiro通过jdbc连接数据库,连接池采用阿里巴巴的druid的连接池 参考文档:https://www.w3cschool.cn/shiro/xgj31if4.html https://w ...
- R in action读书笔记(3)-第六章:基本图形
第六章 基本图形 6.1条形图 条形图通过垂直的或水平的条形展示了类别型变量的分布(频数).函数:barplot(height) 6.1.1简单的条形图 6.1.2推砌条形图和分组条形图 如果hei ...