Description

给您一颗树,每个节点有个初始值。

现在支持以下两种操作:

  1. C i x(0<=x<2^31) 表示将i节点的值改为x。
  2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

解题报告:

用时:1h20min,3WA

简单题,对每一种颜色建一棵树链剖分的数组,可以持久化一下,动态加点,暴力搞搞即可

空间时间复杂度:\(O((n+m)logn)\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=100005;
int n,m,head[N],num=0,to[N<<1],nxt[N<<1],col[N],id[N],DFN=0,b[N<<2],sum=0;
struct question{int flag,x,y,z;}q[N<<1];
void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
int dep[N],top[N],fa[N],sz[N],son[N],tot;char s[3];
void dfs1(int x){
int u;sz[x]=1;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(dep[u])continue;
dep[u]=dep[x]+1;fa[u]=x;
dfs1(u);
sz[x]+=sz[u];
if(sz[u]>sz[son[x]])son[x]=u;
}
}
void dfs2(int x,int tp){
top[x]=tp;id[x]=++DFN;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(to[i]!=son[x] && to[i]!=fa[x])dfs2(to[i],to[i]);
}
int totnode=0,root[N<<2];
struct node{int l,r,s;}t[N*160];
void updata(int &rt,int last,int l,int r,int sa,int to){
rt=++totnode;t[rt]=t[last];
if(l==r){t[rt].s+=to;return ;}
int mid=(l+r)>>1;
if(sa>mid)updata(t[rt].r,t[last].r,mid+1,r,sa,to);
else updata(t[rt].l,t[last].l,l,mid,sa,to);
t[rt].s=t[t[rt].l].s+t[t[rt].r].s;
}
int query(int rt,int l,int r,int sa,int se){
if(l>se || r<sa)return 0;
if(sa<=l && r<=se)return t[rt].s;
int mid=(l+r)>>1;
return query(t[rt].l,l,mid,sa,se)+query(t[rt].r,mid+1,r,sa,se);
}
int solve(int x,int y,int co){
int ret=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ret+=query(root[co],1,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(id[x]>id[y])swap(x,y);
ret+=query(root[co],1,n,id[x],id[y]);
return ret;
}
void work()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&col[i]),b[++sum]=col[i];
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y);link(y,x);
}
dep[1]=1;dfs1(1);dfs2(1,1);
for(int i=1;i<=m;i++){
scanf("%s%d%d",s,&q[i].x,&q[i].y);
if(s[0]=='C')q[i].flag=0,b[++sum]=q[i].y;
else scanf("%d",&q[i].z),q[i].flag=1,b[++sum]=q[i].z;
}
sort(b+1,b+sum+1);
tot=unique(b+1,b+sum+1)-b-1;
for(int i=1;i<=n;i++){
col[i]=lower_bound(b+1,b+tot+1,col[i])-b;
updata(root[col[i]],root[col[i]],1,n,id[i],1);
}
for(int i=1;i<=m;i++){
x=q[i].x;y=q[i].y;
if(q[i].flag==0){
y=lower_bound(b+1,b+tot+1,y)-b;
updata(root[col[x]],root[col[x]],1,n,id[x],-1);
updata(root[y],root[y],1,n,id[x],1);
col[x]=y;
}
else{
q[i].z=lower_bound(b+1,b+tot+1,q[i].z)-b;
printf("%d\n",solve(x,y,q[i].z));
}
}
} int main()
{
work();
return 0;
}

4999: This Problem Is Too Simple!的更多相关文章

  1. bzoj 4999: This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  2. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

  3. 【BZOJ4999】This Problem Is Too Simple!(线段树)

    [BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...

  4. 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA

    [BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2 ...

  5. [BZOJ 4999]This Problem Is Too Simple!

    [BZOJ 4999]This Problem Is Too Simple! 题目 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将 ...

  6. bzoj4999 This Problem Is Too Simple!

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

  7. 2019.03.09 bzoj4999: This Problem Is Too Simple!(树链剖分+线段树动态开点)

    传送门 题意:给一颗树,每个节点有个初始值,要求支持将i节点的值改为x或询问i节点到j节点的路径上有多少个值为x的节点. 思路: 考虑对每种颜色动态开点,然后用树剖+线段树维护就完了. 代码: #in ...

  8. BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树

    题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...

  9. BZOJ4999:This Problem Is Too Simple!(DFS序&树上差分&线段树动态开点:区间修改单点查询)

    Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x&l ...

随机推荐

  1. 亚马逊的PuTTY连接AWS出现network error connection refused,终极解决方案。

    使用PuTTY连接AWS的时候,一直出现network error connection refused.百度了这个问题,大家都说是SSH要设置成22.但是我已经设置过了,为什么还是遇到这个问题呢? ...

  2. centos 安装配置 mysql

    安装环境:CentOS7 64位 MINI版,安装MySQL5.7 1.配置YUM源 在MySQL官网中下载YUM源rpm安装包:http://dev.mysql.com/downloads/repo ...

  3. python安装及写一个简单的验证码组件(配合node)

    1.安装Python 到官网下载响应系统的版本(这里以windows为例):https://www.python.org/downloads/windows/ 然后就是不断地"下一步&quo ...

  4. 24.C++- 抽象类(存虚函数)、接口、多重继承

    抽象类和接口 什么是抽象类 用来表示现实世界中的抽象概念 是一种只能定义类型,而不能产生对象的类 只能被子类继承,且抽象类的相关成员函数没有完整的体现,用来被子类重写. 比如图形(Shape)类, 就 ...

  5. jquery实现对div的拖拽功能

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Spring知识点回顾(06)Profile 和 条件注解 @Conditional

    1.设定环境中的active profiles 如:DispatcherServerlet的init-param spring.profiles.active=production spring.pr ...

  7. Spring Security 入门(1-4-2)Spring Security - 认证过程之AuthenticationProvider的扩展补充说明

    1.用户信息从数据库获取 通常我们的用户信息都不会向第一节示例中那样简单的写在配置文件中,而是从其它存储位置获取,比如数据库.根据之前的介绍我们知道用户信息是通过 UserDetailsService ...

  8. servlet2.3/2.5/3.0/3.1的xml名称空间备忘

    The web.xml is a configuration file to describe how a web application should be deployed. Here’re 5  ...

  9. Spark:如何替换sc.parallelize(List(item1,item2)).collect().foreach(row=>{})为并行?

    代码场景: 1)设定的几种数据场景,遍历所有场景:依次统计满足每种场景条件下的数据,并把统计结果存入hive: 2)已有代码如下: case class IndoorOTTCalibrateBuild ...

  10. SpringMVC(七):@RequestMapping下使用POJO对象绑定请求参数值

    Spring MVC会按照请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值,支持级联属性. 如:address.city.dept.address.province等. 步骤一:定义Ac ...