3531: [Sdoi2014]旅行

Time Limit: 20 Sec  Memory Limit: 512 MB

Submit: 850  Solved: 433

[Submit][Status][

id=3531" style="color:blue; text-decoration:none">Discuss]

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

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

Sample Output

8

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】旅行的更多相关文章

  1. Bzoj3531: [Sdoi2014]旅行

    Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1698  Solved: 758 Description S国有N个城市,编号从1到N.城市间用N-1 ...

  2. BZOJ3531 [Sdoi2014]旅行 树链剖分 线段树

    原文链接:http://www.cnblogs.com/zhouzhendong/p/8080189.html 题目传送门 - BZOJ3531 题意概括 一棵树,n个节点,每一个节点两个值,一个颜色 ...

  3. BZOJ3531[Sdoi2014]旅行——树链剖分+线段树

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...

  4. BZOJ3531:[SDOI2014]旅行(树链剖分)

    Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...

  5. BZOJ3531 [Sdoi2014]旅行 【树剖 + 线段树】

    题目 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们用 ...

  6. [bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)

    Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. ...

  7. 2018.07.24 bzoj3531: [Sdoi2014]旅行(树链剖分+动态开点)

    传送门 树链剖分. 如何维护? 如果颜色少直接每种颜色一颗线段树走人. 但这题颜色数量不大于1e5" role="presentation" style="po ...

  8. 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行

    离线后以宗教为第一关键字,操作时间为第二关键字排序. <法一>块状树,线下ac,线上tle…… #include<cstdio> #include<cmath> # ...

  9. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

  10. bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)

    感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...

随机推荐

  1. Python的支持工具[0] -> 环境包管理工具[0] -> pip

    pip包管理工具 / pip Package Management Tools pip是一个Python包管理工具,主要是用于安装PyPI上的软件包,可以替代easy_install工具. 1 pip ...

  2. ELK帮助文档

    elasticsearch: API中文指南:https://es.xiaoleilu.com/010_Intro/15_API.html 官方文档:https://www.elastic.co/cn ...

  3. 浅析 Node.js 单线程模型

    总结笔记:对于每个用户请求,由主线程接收并存放于一个事件队列中(不做任何处理),当无请求发生时,即主线程空闲,主线程开始循环处理事件队列中的任务: 对于非阻塞JS程序: 1.若某事件需要I/O操作,则 ...

  4. 新博客:11101001.com

    开了一个新blog 但还是会用这个写博客 新博客地址11101001.com

  5. easyui combogrid 按需加载,点击下拉加载

    功能优点:减少不必要的http请求,减少服务器查询压力,降低额外的浏览器渲染,提高呈现速度开发分享: combogrid 点击才请求的功能实现简要:我分析了费用系统,和现在全网的写法.并不满意.都是要 ...

  6. MySQL索引,MySQL中索引的限制?

    MySQL中索引的限制: 1.MyISAM存储引擎引键的长度综合不能超过1000字节: 2.BLOB和TEXT类型的列只能创建前缀索引: 3.MySQL目前不支持函数索引: 4.使用!= 或者< ...

  7. sharepoint2010无法连接到配置数据库。

    最近VS部署又遇到这个问题了,记录一下. 然后以管理员省份打开sharePoint管理中心,发现页面展示光秃秃的“无法连接到配置数据库” 解决方式:问的同事. 找到计算机 服务 项, 这个启动下 这个 ...

  8. VBA Collection用法总结

    Sub test() ' Dim s As Collection '定义s变量为集合对象 ' Set s = New Collection '初始化集合对象s (否则无法使用) Dim s As Ne ...

  9. DotNetBrowser入门教程(更新完善中)

    DotNetBrowser 希望实现的目标:桌面软件可以完美运行Html5,内置支持MVC与WebSocket的微型服务器. 基于.Net 4.0开发.开发环境:VS2017,运行环境支持Window ...

  10. tomcat下载安装以及在eclipse中的配置

    eclipse的下载地址是http://www.eclipse.org/downloads/. tomcat的下载地址为http://tomcat.apache.org/ 这两个工具的安装都非常eas ...