[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条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
随机推荐
- antd-design TextArea initialValue 不生效可能原因
<Form.Item label="展会介绍"> {getFieldDecorator('introduce', { initialValue:record.intro ...
- EDK II之Secure Boot简述
密钥对:公钥分发,私钥自留.常见的公钥格式:cer/der,常见的私钥格式:pfx. BIOS中Secure Boot的原理:把公钥包在code里面,当使用gBS->LoadImage()去加载 ...
- xtrabackup 2.4.3 BUG
用XtraBackup对备份集进行apply log 的时候,卡在 xtrabackup 版本:2.4.3 InnoDB: Waited for 1535930 seconds for 128 pen ...
- python操作pymysql数据库
首先需要导入通过import pymysql导入数据库模块 已经创建好一个数据库test,数据库中有一个空表t,只有两个字段id int(5),name varchar(20) import pymy ...
- 使用AtomicLong,经典银行账户问题
1.新建Account类,使用AtomicLong定义账户余额,增加和减少金额方法使用getAndAdd方法. package com.xkzhangsan.atomicpack.bank; impo ...
- 【题解】Luogu P5251 [LnOI2019]第二代图灵机
原题传送门 前置芝士:珂朵莉树 珂朵莉树的主要功能是区间赋值 这道题还算明显(操作2) 一开始看见这题觉得很毒瘤,但仔细想想发现颜色和数字之间没有什么关系 我们一共要维护三个东西: 1.区间和:树状数 ...
- mfc动态控件生成
1.变量.函数声明 std::vector<CButton*>pBtn; afx void OnBtnClik(UINT uID);//回调函数 2.分配空间 pBtn.resize(50 ...
- maven中引入oracle驱动报错Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
转自https://blog.csdn.net/lovesomnus/article/details/49512777 在maven中央库中查找ojdbc,发现最新的版本是10.2.0.4.0,然后在 ...
- net应用程序池自动关闭的解决方法
while (true) { using (ServerManager sm = ServerManager.OpenRemote("localhost")) { string p ...
- 论文笔记:Learning Attribute-Specific Representations for Visual Tracking
Learning Attribute-Specific Representations for Visual Tracking AAAI-2019 Paper:http://faculty.ucmer ...