[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条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
随机推荐
- HTML5新增常用属性
一. 代码名称语义化的好处 1.能让搜索引擎更好的收录 2.对于特殊设备如盲人设备好解析 二.article和section的区别 article(文章):独立且能被外部引用 section(章节.段 ...
- Python 嘉宾列表问题
某书上的练习题,当作复习8 #3-5 修改嘉宾名单 def alter(someone, other): if someone in din_list: din_list.remove(someone ...
- LInux命令英文全称
Linux命令英文全称 su = Swith user 切换用户,切换到root用户cat = Concatenate 串联uname = Unix name 系统名称df = Disk free ...
- 3.键盘输入10个数,放到数组中,(1)去除该数组中大于10的数 (2)将该数组中的数字写入到本地文件number.txt中
package cn.it.text; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; ...
- 打印word文档时遇到标记区如何取消
故障描述:word页面显示正常,打印以及打印预览的时候,页面上会出现部分暗色区域(标记区) 故障原因:简单标记惹的祸 解决办法:word菜单栏-审阅-简单标记 ...
- P2598 [ZJOI2009]狼和羊的故事(网络流)
P2598 [ZJOI2009]狼和羊的故事 源点和所有狼连 $inf$ 的边 所有羊和汇点连 $inf$ 的边 所有点向四周连 $1$ 的边 这样所有狼和羊之间的边都被割掉了 统计最小割就好辣 #i ...
- Java锁与CAS
一.加锁与无锁CAS 在谈论无锁概念时,总会关联起乐观派与悲观派,对于乐观派而言,他们认为事情总会往好的方向发展,总是认为坏的情况发生的概率特别小,可以无所顾忌地做事,但对于悲观派而已,他们总会认为发 ...
- Java基础学习-常量和变量
1.常量概述 -在程序执行的过程中,其值不可以发生改变的量. 2.常量的分类 -字符串常量 用双引号括起来的内容("HelloWorld") -整数常 ...
- Struts2---动态action以及应用
为了处理各种逻辑业务,根据execute方法来判断请求哪种业务,然后将请求转发到对应的业务处理上, 通过动态请求action对象中的方法,实现某个单一的业务逻辑处理. 动态action的应用 //创建 ...
- python程序—系统检测
监控系统内存,CPU,硬盘的使用情况,到达阈值时会自动发送邮件报警! import yagmail import psutil def sendmail(subject,contents): #连接邮 ...