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. Git&GitHun 命令合集

    Git&GitHun 命令合集 基本操作 git --version 查看git版本信息 git add 本地库初始化 设置签名 git config user.name xxx git co ...

  2. URl 传参时+号变成空格

    前端用base64加密后的数据,传递到后台时发现一个问题: 比如 韩飞 这个名字,base64加密后的字符串为 6Z+p6aOe 但是后端接受到参数为: 6Z p6aOe +号变成了空格,导致后台解密 ...

  3. ReactiveCocoa(二)

    前言 通过ReactiveCocoa(一)的学习,相信大家对ReactiveCocoa有了一些基本认识吧.下面就让我们来学习ReactiveCocoa的一些基本使用吧! ReactiveCocoa基本 ...

  4. [CP1804]最短路

    题目大意: 一个$n(n\le10^5)$个点的图,给定一个常数$c$,每对点$i,j$之间有权值为$(i\oplus j)\times c$的边.另有$m(m\le5\times10^5)$条指定权 ...

  5. hdu 5206 Four Inages Strategy 计算几何

    题目链接:HDU - 5206 Young F found a secret record which inherited from ancient times in ancestral home b ...

  6. 【OpenJudge7624】【区间DP】山区建小学

    山区建小学 总时间限制: 1000ms 内存限制: 65536kB [描述] 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两 ...

  7. SQL SERVER Update from 使用陷阱

    原文:SQL SERVER Update from 使用陷阱 update A set from A left join B on 此方法常用来使用根据一个表更新另一个表的数据,来进行数据同步更新.若 ...

  8. UIViewController的生命周期及iOS程序运行顺序

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的运行顺序 1. alloc                                   创建对象,分配空间 2.init (initWit ...

  9. Java:网络编程值TCP的使用

    演示TCP传输   1.Tcp分客户端和服务端 2.客服端对应的对象是scoket    服务端对应的对象是serverscoket   客户端: 通过查阅scoket对象,发现在建立对象时,就可以连 ...

  10. 在vs2012中配置使用iisexpress

    在vs2012中配置使用iisexpress   vs2012支持基于iisexpress的web站点调试,这样可以尽可能与生产环境具备一样的环境. 但是,如果在vs2012中直接配置iis目录,通常 ...