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. 前端常用面试题目及答案-HTML&CSS篇

    1. 行内元素和块级元素有哪些? 行内元素: 123456789101112131415161718192021222324252627 <a>     //标签可定义锚   <ab ...

  2. 替换Ubuntu默认的登录背景

    Ubuntu默认的登录背景看起来还是比较高贵的,但是作为一个爱折腾的人,当然要换成自己喜欢的背景图了.一开始跟着百度走,进了不少坑,最后还是自己走出来的.先上一个成品照 百度得到的答案几乎都是安装ub ...

  3. Palindrome Permutation -- LeetCode

    Given a string, determine if a permutation of the string could form a palindrome. For example," ...

  4. linux下安装 tomcat

    1.首先配置jdk,上篇文章中有具体的介绍. 2.官网下载tomcat:https://tomcat.apache.org/download-80.cgi (下载 tar.gz 的版本 ) 3.上传压 ...

  5. SQL表操作习题6 36~45题

  6. linux下打包,压缩,解压缩

    Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲ta ...

  7. CGCS2000坐标系与其他坐标系间的差异和转换方法

    转自 CGCS2000坐标系与其他坐标系间的差异和转换方法 1954北京坐标系和1980西安坐标系是以天文大地网等经典测量技术为基础的局部坐标系.­ CGCS2000是以地球质量中心为原点的地心大地坐 ...

  8. [置顶] kubernetes资源类型--PetSets/StatefulSet

    PetSet首次在K8S1.4版本中,在1.5更名为StatefulSet.除了改了名字之外,这一API对象并没有太大变化. 注意:以下内容的验证环境为CentOS7.K8S版本1.5.2,并部署Sk ...

  9. Bloom Filter的应用

    1.布隆过滤器是什么? 又快又小的处理方法 布隆过滤器(Bloom Filter):是一种空间效率极高的概率型算法和数据结构,用于判断一个元素是否在集合中(类似Hashset). 它的核心一个很长的二 ...

  10. 2017.7.1 nginx反向代理服务器域名解析配置(已验证可使用)

    下载地址:http://learning.happymmall.com/ 前提:ftpserver已经开启,并且设置为: 1.获得安装文件 2.修改配置文件 2.1 修改conf/nginx.conf ...