bzoj3531【SDOI2014】旅行
3531: [Sdoi2014]旅行
Time Limit: 20 Sec Memory Limit: 512 MB id=3531" style="color:blue; text-decoration:none">Discuss
Submit: 850 Solved: 433
[Submit][Status][
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
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
Sample Output
9
11
3
HINT
N,Q < =10^5 , C < =10^5
数据保证对全部QS和QM事件,起点和终点城市的信仰同样;在随意时
刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。
Source
树链剖分,对于每一种信仰建一棵线段树,动态开点。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 100005
#define maxm 10000005
using namespace std;
int n,m,cnt,tot,x,y;
int p[maxn],sz[maxn],head[maxn],belong[maxn],d[maxn],f[maxn][17];
int w[maxn],c[maxn],rt[maxn],ls[maxm],rs[maxm],mx[maxm],sum[maxm];
bool vst[maxn];
char ch[10];
struct edge_type
{
int next,to;
}e[maxn*2];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void add_edge(int x,int y)
{
e[++cnt]=(edge_type){head[x],y};head[x]=cnt;
e[++cnt]=(edge_type){head[y],x};head[y]=cnt;
}
inline void dfs1(int x)
{
for(int i=1;i<=16;i++)
{
if ((1<<i)<=d[x]) f[x][i]=f[f[x][i-1]][i-1];
else break;
}
vst[x]=true;sz[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if (vst[y]) continue;
d[y]=d[x]+1;
f[y][0]=x;
dfs1(y);
sz[x]+=sz[y];
}
}
inline void dfs2(int x,int chain)
{
p[x]=++tot;belong[x]=chain;
int k=0;
for(int i=head[x];i;i=e[i].next)
if (d[e[i].to]>d[x]&&sz[k]<sz[e[i].to]) k=e[i].to;
if (k) dfs2(k,chain);
for(int i=head[x];i;i=e[i].next)
if (d[e[i].to]>d[x]&&e[i].to!=k) dfs2(e[i].to,e[i].to);
}
inline int lca(int x,int y)
{
if (d[x]<d[y]) swap(x,y);
int t=int(log2(d[x]-d[y]));
D(i,t,0) if (d[x]-(1<<i)>=d[y]) x=f[x][i];
if (x==y) return x;
t=int(log2(d[x]));
D(i,t,0) if (f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}
return f[x][0];
}
inline void pushup(int k)
{
mx[k]=max(mx[ls[k]],mx[rs[k]]);
sum[k]=sum[ls[k]]+sum[rs[k]];
}
inline void change(int &k,int l,int r,int x,int num)
{
if (!k) k=++tot;
if (l==r){mx[k]=sum[k]=num;return;}
int mid=(l+r)>>1;
if (x<=mid) change(ls[k],l,mid,x,num);
else change(rs[k],mid+1,r,x,num);
pushup(k);
}
inline int getmx(int k,int l,int r,int x,int y)
{
if (!k) return 0;
if (l==x&&r==y) return mx[k];
int mid=(l+r)>>1;
if (y<=mid) return getmx(ls[k],l,mid,x,y);
else if (x>mid) return getmx(rs[k],mid+1,r,x,y);
else return max(getmx(ls[k],l,mid,x,mid),getmx(rs[k],mid+1,r,mid+1,y));
}
inline int getsum(int k,int l,int r,int x,int y)
{
if (!k) return 0;
if (l==x&&r==y) return sum[k];
int mid=(l+r)>>1;
if (y<=mid) return getsum(ls[k],l,mid,x,y);
else if (x>mid) return getsum(rs[k],mid+1,r,x,y);
else return getsum(ls[k],l,mid,x,mid)+getsum(rs[k],mid+1,r,mid+1,y);
}
inline int solvemx(int c,int x,int tmp)
{
int mx=0;
while (belong[x]!=belong[tmp])
{
mx=max(mx,getmx(rt[c],1,n,p[belong[x]],p[x]));
x=f[belong[x]][0];
}
mx=max(mx,getmx(rt[c],1,n,p[tmp],p[x]));
return mx;
}
inline int solvesum(int c,int x,int tmp)
{
int sum=0;
while (belong[x]!=belong[tmp])
{
sum+=getsum(rt[c],1,n,p[belong[x]],p[x]);
x=f[belong[x]][0];
}
sum+=getsum(rt[c],1,n,p[tmp],p[x]);
return sum;
}
int main()
{
n=read();m=read();
F(i,1,n){w[i]=read();c[i]=read();}
F(i,1,n-1){x=read();y=read();add_edge(x,y);}
dfs1(1);dfs2(1,1);
tot=0;
F(i,1,n) change(rt[c[i]],1,n,p[i],w[i]);
F(i,1,m)
{
scanf("%s",ch);x=read();y=read();
if (ch[0]=='C')
{
if (ch[1]=='C')
{
change(rt[c[x]],1,n,p[x],0);change(rt[y],1,n,p[x],w[x]);
c[x]=y;
}
else{change(rt[c[x]],1,n,p[x],y);w[x]=y;}
}
else
{
int tmp=lca(x,y);
if (ch[1]=='S')
{
int ans=solvesum(c[x],x,tmp)+solvesum(c[x],y,tmp);
if (c[x]==c[tmp]) ans-=w[tmp];
printf("%d\n",ans);
}
else printf("%d\n",max(solvemx(c[x],x,tmp),solvemx(c[x],y,tmp)));
}
}
}
bzoj3531【SDOI2014】旅行的更多相关文章
- Bzoj3531: [Sdoi2014]旅行
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1698 Solved: 758 Description S国有N个城市,编号从1到N.城市间用N-1 ...
- 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条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...
- 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 旅行 - 树链剖分,主席树
题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...
- bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...
随机推荐
- Python的支持工具[0] -> 环境包管理工具[0] -> pip
pip包管理工具 / pip Package Management Tools pip是一个Python包管理工具,主要是用于安装PyPI上的软件包,可以替代easy_install工具. 1 pip ...
- ELK帮助文档
elasticsearch: API中文指南:https://es.xiaoleilu.com/010_Intro/15_API.html 官方文档:https://www.elastic.co/cn ...
- 浅析 Node.js 单线程模型
总结笔记:对于每个用户请求,由主线程接收并存放于一个事件队列中(不做任何处理),当无请求发生时,即主线程空闲,主线程开始循环处理事件队列中的任务: 对于非阻塞JS程序: 1.若某事件需要I/O操作,则 ...
- 新博客:11101001.com
开了一个新blog 但还是会用这个写博客 新博客地址11101001.com
- easyui combogrid 按需加载,点击下拉加载
功能优点:减少不必要的http请求,减少服务器查询压力,降低额外的浏览器渲染,提高呈现速度开发分享: combogrid 点击才请求的功能实现简要:我分析了费用系统,和现在全网的写法.并不满意.都是要 ...
- MySQL索引,MySQL中索引的限制?
MySQL中索引的限制: 1.MyISAM存储引擎引键的长度综合不能超过1000字节: 2.BLOB和TEXT类型的列只能创建前缀索引: 3.MySQL目前不支持函数索引: 4.使用!= 或者< ...
- sharepoint2010无法连接到配置数据库。
最近VS部署又遇到这个问题了,记录一下. 然后以管理员省份打开sharePoint管理中心,发现页面展示光秃秃的“无法连接到配置数据库” 解决方式:问的同事. 找到计算机 服务 项, 这个启动下 这个 ...
- VBA Collection用法总结
Sub test() ' Dim s As Collection '定义s变量为集合对象 ' Set s = New Collection '初始化集合对象s (否则无法使用) Dim s As Ne ...
- DotNetBrowser入门教程(更新完善中)
DotNetBrowser 希望实现的目标:桌面软件可以完美运行Html5,内置支持MVC与WebSocket的微型服务器. 基于.Net 4.0开发.开发环境:VS2017,运行环境支持Window ...
- tomcat下载安装以及在eclipse中的配置
eclipse的下载地址是http://www.eclipse.org/downloads/. tomcat的下载地址为http://tomcat.apache.org/ 这两个工具的安装都非常eas ...