[luogu P3313] [SDOI2014]旅行
[luogu P3313] [SDOI2014]旅行
题目描述
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,并记下了途中留宿过的城市的评级最大值。
由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。 为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。
输入输出格式
输入格式:
输入的第一行包含整数N,Q依次表示城市数和事件数。 接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的评级和信仰。 接下来N-1行每行两个整数x,y表示一条双向道路。 接下来Q行,每行一个操作,格式如上所述。
输出格式:
对每个QS和QM事件,输出一行,表示旅行者记下的数字。
输入输出样例
输入样例#1: 复制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输出样例#1: 复制8 9 113说明
N,Q < =10^5 , C < =10^5
数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时
刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。
显然和树剖有关。
然后我们发现宗教信仰有点恶心。
怎么办呢?对于每一种信仰建一棵线段树——>指针实现。
这样的话,我们相当于只需要维护信仰种类棵“动态开点线段树”。
然后相应维护一下几个操作就可以了。
code:
#include <cstdio> #include <cstring> #include <algorithm> #define ms(a,x) memset(a,x,sizeof a) typedef long long LL; void OJ() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif } namespace fastIO { #define puc(c) putchar(c) char ch; inline int read() { ,f=; ch=getchar(); ') { if (ch=='-') f=-f; ch=getchar(); } ') { x=(x<<)+(x<<)+ch-'; ch=getchar(); } return x*f; } inline char readc() { ch=getchar(); while (ch<'A'||ch>'Z') { ch=getchar(); } return ch; } ]; template <class T> inline void write(T x) { ) { puc('); return; } ; x; x/=) num[++cnt]=x%; ); } inline void newline() { puc('\n'); } } using namespace fastIO; ; int n,w[N],c[N],pos[N]; #define sgt node struct sgt { node* l,* r; int s,m; node () { l=r=; s=m=; } inline void init (node* c) { c=; } #define max(a,b) ((a)>(b)?(a):(b)) inline void update (node* c) { c->s=; if (c->l) c->s+=c->l->s; if (c->r) c->s+=c->r->s; c->m=; if (c->l) c->m=max(c->m,c->l->m); if (c->r) c->m=max(c->m,c->r->m); } #define M ((l)+(r)>>1) inline void modify (node* &c,int l,int r,int x,int w) { if (l>r) return; if (!c) c=new node(); if (l==r) { c->m=w,c->s=w; return; } if (x<=M) modify(c->l,l,M,x,w); ,r,x,w); update(c); } inline ) { ; if (x<=l&&r<=y) return c->s; if (y<=M) ret=reply_s(c->l,l,M,x,y); else ,r,x,y); else ret=reply_s(c->l,l,M,x,y)+reply_s(c->r,M+,r,x,y); return ret; } inline ) { ; if (x<=l&&r<=y) return c->m; if (y<=M) ret=reply_m(c->l,l,M,x,y); else ,r,x,y); else ret=max(reply_m(c->l,l,M,x,y),reply_m(c->r,M+,r,x,y)); return ret; } } sg,*s[N]; class TCP { private: ],son[N<<]; int fa[N],dep[N],siz[N],got[N]; int clo,dfn[N],top[N]; public: inline void init() { tot=,ms(lnk,),ms(nxt,); fa[]=,dep[]=,siz[]=; clo=; } inline void add(int x,int y) { nxt[++tot]=lnk[x],lnk[x]=tot,son[tot]=y; } inline void dfs(int x,int p) { fa[x]=p,dep[x]=dep[p]+,siz[x]=,got[x]=; for (int j=lnk[x]; j; j=nxt[j]) { if (son[j]==p) continue; dfs(son[j],x); siz[x]+=siz[son[j]]; if (siz[son[j]]>siz[got[x]]) got[x]=son[j]; } } inline void redfs(int x,int r) { dfn[x]=++clo,pos[clo]=x,top[x]=r; if (got[x]) redfs(got[x],r); for (int j=lnk[x]; j; j=nxt[j]) { if (son[j]==fa[x]||son[j]==got[x]) continue; redfs(son[j],son[j]); } } inline void modify (int c,int x,int w) { sg.modify(s[c],,n,dfn[x],w); } #define max(a,b) ((a)>(b)?(a):(b)) inline ) { while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) std::swap(x,y); ret+=sg.reply_s(s[c],,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if (dep[x]<dep[y]) std::swap(x,y); ret+=sg.reply_s(s[c],,n,dfn[y],dfn[x]); return ret; } inline ) { while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) std::swap(x,y); ret=max(ret,sg.reply_m(s[c],,n,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if (dep[x]<dep[y]) std::swap(x,y); ret=max(ret,sg.reply_m(s[c],,n,dfn[y],dfn[x])); return ret; } } t; int m; int main() { OJ(); char opt; int x,y; n=read(),m=read(),t.init(); ; i<=; ++i) sg.init(s[i]); ; i<=n; ++i) w[i]=read(),c[i]=read(); ; i<n; ++i) { x=read(),y=read(); t.add(x,y),t.add(y,x); } t.dfs(,),t.redfs(,); ; i<=n; ++i) t.modify(c[i],i,w[i]); for ( ; m; --m) { opt=readc(); if (opt=='C') { opt=readc(),x=read(),y=read(); if (opt=='C') { t.modify(c[x],x,); t.modify(c[x]=y,x,w[x]); } else { t.modify(c[x],x,w[x]=y); } } else { opt=readc(),x=read(),y=read(); if (opt=='S') { write(t.reply_s(c[x],x,y)); newline(); } else { write(t.reply_m(c[x],x,y)); newline(); } } } ; }
[luogu P3313] [SDOI2014]旅行的更多相关文章
- 洛谷 P3313 [SDOI2014]旅行 解题报告
P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...
- P3313 [SDOI2014]旅行
P3313 [SDOI2014]旅行 树链剖分+动态线段树(并不是lct) 显然的,我们对于每一个宗教都要维护一个线段树. (那么空间不是爆炸了吗) 在这里引入:动态开点线段树 就是需要的点开起来,不 ...
- P3313 [SDOI2014]旅行——树链剖分+线段树(动态开点?)
P3313 [SDOI2014]旅行 一棵树,其中的点分类,点有权值,在一条链上找到一类点中的最大值或总和: 树链剖分把树变成链: 把每个宗教单开一个线段树,维护区间总和和最大值: 宗教很多,需要动态 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 洛谷 P3313 [SDOI2014]旅行
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- [SDOI2014]旅行
洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
随机推荐
- python画手绘图
第一步:插入代码 #e17.1HandDrawPic.py from PIL import Image import numpy as np vec_el = np.pi/2.2 # 光源的俯视角度, ...
- Maven Webapp项目web.xml版本记录
web.xml 2.0版本 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3// ...
- 【题解】Luogu P4198 楼房重建
原题传送门 根据斜率来建线段树,线段树维护区间最大斜率以及区间内能看见的楼房的数量(不考虑其他地方的原因,两个节点合并时再考虑) 细节见程序 #include <bits/stdc++.h> ...
- Algorithm 学习环境准备
工作快5年了,因为是半路学习软件开发, 最近准备刷 LeetCode 复习基础, 看了一集 YouTube 视频 直通硅谷之路讲座 决定搭建一个 不依托于 编辑器 类似白板的开发环境, 因为 Atom ...
- [C++ Primer Plus] 第10章、对象和类(一)程序清单——辨析三个const
程序清单10.1+10.2+10.3 头文件stock.h #ifndef STOCK00_H_ //先测试x是否被宏定义过 #define STOCK00_H_ //如果没有宏定义,就宏定义x并编译 ...
- C#线程同步(4)- 通知&EventWaitHandle一家
文章原始出处 http://xxinside.blogbus.com/logs/47523285.html 预备知识:C#线程同步(1)- 临界区&Lock,C#线程同步(2)- 临界区&am ...
- Vue学习(一)Vue目录结构
安装教程网上一大把,可以自己搜索.记录下学习过程. 认识下Vue的目录结构,取自:https://www.cnblogs.com/dragonir/p/8711761.html vue 文件目录结构详 ...
- CF932G Palindrome Partition
思路 首先把字符串变为\(S[1]S[n]s[2]s[n-1] \dots\) 这样原来的一个合法的划分方案就变成了用k个长度为偶数的回文子串划分的方案, 然后直接DP,对i位置,可转移的位置就是它的 ...
- (转)AutoML for Data Augmentation
AutoML for Data Augmentation 2019-04-01 09:26:19 This blog is copied from: https://blog.insightdatas ...
- _spellmod_base
技能基础修改(进去可能会改动) 可以配合数据库的spell_dbc在线制作无补丁技能. 具体效果查询DBC表 `spellid` int(11) NOT NULL DEFAULT '0', `Effe ...