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

题面

BZOJ

题解

对于每个值,维护一棵线段树就好啦

动态开点,否则空间开不下

剩下的就是很简单的问题啦

当然了,对于数值要离散化

没必要离线吧,在线用\(map\)维护就行了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 120000
#define lson (t[x].ls)
#define rson (t[x].rs)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
map<int,int> M;
int tim,dfn[MAX],hson[MAX],size[MAX],fa[MAX],top[MAX],C[MAX],dep[MAX];
void dfs1(int u,int ff)
{
fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff)continue;
dfs1(v,u);
if(size[v]>size[hson[u]])hson[u]=v;
size[u]+=size[v];
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=fa[u]&&e[i].v!=hson[u])
dfs2(e[i].v,e[i].v);
}
struct Node{int ls,rs,v;}t[MAX<<7];
int tot,sum,rt[MAX<<2];
int n,Q;
void Modify(int &x,int l,int r,int p,int w)
{
if(!x)x=++tot;t[x].v+=w;
if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)Modify(lson,l,mid,p,w);
else Modify(rson,mid+1,r,p,w);
}
int Query(int x,int l,int r,int L,int R)
{
if((!t[x].v)||(!x))return 0;
if(L<=l&&r<=R)return t[x].v;
int mid=(l+r)>>1,ret=0;
if(L<=mid)ret+=Query(lson,l,mid,L,R);
if(R>mid)ret+=Query(rson,mid+1,r,L,R);
return ret;
}
int Route(int u,int v,int x)
{
int ret=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
ret+=Query(rt[x],1,n,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
ret+=Query(rt[x],1,n,dfn[v],dfn[u]);
return ret;
}
int main()
{
n=read();Q=read();
for(int i=1;i<=n;++i)C[i]=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);dfs2(1,1);
for(int i=1;i<=n;++i)
{
if(!M[C[i]])M[C[i]]=++sum;
Modify(rt[M[C[i]]],1,n,dfn[i],1);
}
char ch[5];
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='C')
{
int u=read(),x=read();
Modify(rt[M[C[u]]],1,n,dfn[u],-1);
if(!M[x])M[x]=++sum;
Modify(rt[M[x]],1,n,dfn[u],1);
C[u]=x;
}
else
{
int u=read(),v=read(),x=read();
if(!M[x])puts("0");
else printf("%d\n",Route(u,v,M[x]));
}
}
return 0;
}

【BZOJ4999】This Problem Is Too Simple!(线段树)的更多相关文章

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

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

  2. POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)

    POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...

  3. POJ 3468 A Simple Problem with Integers 【线段树】

    题目链接 http://poj.org/problem?id=3468 思路 线段树 区间更新 模板题 在赋初始值的时候,按点更新区间就可以 AC代码 #include <cstdio> ...

  4. [Codeforces 464E] The Classic Problem(可持久化线段树)

    [Codeforces 464E] The Classic Problem(可持久化线段树) 题面 给出一个带权无向图,每条边的边权是\(2^{x_i}(x_i<10^5)\),求s到t的最短路 ...

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

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

  6. 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树

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

  7. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...

  8. POJ 3468 A Simple Problem with Integers(线段树区间更新区间查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92632   ...

  9. POJ 3468:A Simple Problem with Integers(线段树区间更新模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 141093 ...

  10. POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120 ...

随机推荐

  1. jmeter阶梯加压线程组

    添加阶梯加压线程组路径为鼠标捕获测试计划后,点击鼠标右键->添加->Threads(Users)->jp@gc – Stepping Thread Group(deprecated) ...

  2. Oracle扩展包(pipe,alert,job,scheduler)

    --定义包中函数的纯度级别 create or replace package purityTest is type dept_typ is table of dept%rowtype index b ...

  3. 安装配置heapster(包含influxdb,grafana)

    前提:已搭建好kubernetes集群.安装完dashboard 默认安装的dashboard无法展示集群的度量指标信息,此时就需要安装heapster插件 Heapster 插件使用包含三部分内容: ...

  4. linux一切皆文件之Unix domain socket描述符(二)

    一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.主要用于 ...

  5. python正则表达式,以及应用[下载图片]

    regular expresion由一系列特定字符及其组合成的字符串,用来对目标字符串进行过滤操作.. re相关知识点 python正则表达式库为re,用import re导入,在然后用re.comp ...

  6. 20172311『Java程序设计』课程 结对编程练习_四则运算第一周阶段总结

    20172311『Java程序设计』课程 结对编程练习_四则运算第一周阶段总结 结对伙伴 学号 :20172307 姓名 :黄宇瑭 伙伴第一周博客地址: http://www.cnblogs.com/ ...

  7. HDU3629(凸四边形的个数)

    HDU 3629 计算几何 题目描述:给你n个点(4~700), 问你能够成多少个不同的凸四边形. 解题报告: 暴力的话C(700,4)必然超时,发现,任何一个凹包必然是其中一点在其它3点构成的三角形 ...

  8. 【CSAPP笔记】11. 存储器层次结构

    在没有专门研究存储器系统之前,我们依赖的存储器模型是一个很简单的概念,也就是把它看成一个线性数组,CPU 能在一个常数时间内访问任何一个存储器位置.虽然在研究别的问题时,这是一个有效的模型,但是它不能 ...

  9. STL的集合set

    集合: 集合是由元素组成的一个类,其成员可以是一个集合,也可以是一个原子,通常一个元素在一个集合中不能多次出现:由于对实现集合不是很理解,只简单写下已有的STL中的set集合使用: C++中set基本 ...

  10. 关于51精确延时及keil仿真延时时间

    转自:http://blog.sina.com.cn/s/blog_980e19e00101b5dh.html 有时候需要精确的延时,比如18B20温度传感器对时序要求非常严格,必须精确到微秒级别 一 ...