[BZOJ 4999]This Problem Is Too Simple!
[BZOJ 4999]This Problem Is Too Simple!
题目
给您一颗树,每个节点有个初始值。现在支持以下两种操作:1. C i x(0<=x<2^31) 表示将i节点的值改为x。2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。INPUT
第一行有两个整数N,Q(1 ≤N≤ 100,000;1 ≤Q≤ 200,000),分别表示节点个数和操作个数。下面一行N个整数,表示初始时每个节点的初始值。接下来N-1行,每行两个整数x,y,表示x节点与y节点之间有边直接相连(描述一颗树)。接下来Q行,每行表示一个操作,操作的描述已经在题目描述中给出。OUTPUT
对于每个Q输出单独一行表示所求的答案。
SAMPLE
INPUT
5 6
10 20 30 40 50
1 2
1 3
3 4
3 5
Q 2 3 40
C 1 40
Q 2 3 40
Q 4 5 30
C 3 10
Q 4 5 30OUTPUT
0
1
1
0
解题报告
树剖+权值线段树动态开点+离散
随便搞搞就行了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
inline int read(){
int sum();
char ch(getchar());
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
return sum;
}
struct edge{
int e;
edge *n;
}ed[],*pre[];
int tot;
inline void insert(int s,int e){
ed[++tot].e=e;
ed[tot].n=pre[s];
pre[s]=&ed[tot];
}
map<int,int>ma;
int num;
int n,q;
int a[];
int dep[],size[],fa[],son[];
inline void dfs1(int u){
size[u]=;
son[u]=;
for(edge *i=pre[u];i;i=i->n){
int e(i->e);
if(e!=fa[u]){
fa[e]=u;
dep[e]=dep[u]+;
dfs1(e);
size[u]+=size[e];
if(size[e]>size[son[u]])
son[u]=e;
}
}
}
int timee;
int id[],pos[],top[];
inline void dfs2(int u,int rt){
top[u]=rt;
id[u]=++timee;
pos[timee]=u;
if(son[u])
dfs2(son[u],rt);
for(edge *i=pre[u];i;i=i->n){
int e(i->e);
if(e!=fa[u]&&e!=son[u])
dfs2(e,e);
}
}
int cnt;
int rt[],lch[],rch[],sum[];
inline void update(int &x,int pos,int w,int l,int r){
if(!x)
x=++cnt;
sum[x]+=w;
if(l==r)
return;
int mid((l+r)>>);
if(pos<=mid)
update(lch[x],pos,w,l,mid);
else
update(rch[x],pos,w,mid+,r);
}
inline int query(int x,int ll,int rr,int l,int r){
if(!x)
return ;
if(ll<=l&&r<=rr)
return sum[x];
int mid((l+r)>>),ret();
if(ll<=mid)
ret+=query(lch[x],ll,rr,l,mid);
if(mid<rr)
ret+=query(rch[x],ll,rr,mid+,r);
return ret;
}
inline int ask(int x,int y,int z){
int ret(),tmp(ma[z]);
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ret+=query(rt[tmp],id[top[x]],id[x],,n);
x=fa[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ret+=query(rt[tmp],id[x],id[y],,n);
return ret;
}
char op[];
int main(){
memset(pre,NULL,sizeof(pre));
n=read(),q=read();
for(int i=;i<=n;++i)
a[i]=read();
for(int i=;i<n;++i){
int x(read()),y(read());
insert(x,y),insert(y,x);
}
dfs1();
dfs2(,);
for(int i=;i<=n;++i){
if(!ma[a[i]])
ma[a[i]]=++num;
update(rt[ma[a[i]]],id[i],,,n);
}
while(q--){
scanf("%s",op);
if(op[]=='C'){
int x(read()),y(read());
update(rt[ma[a[x]]],id[x],-,,n);
if(!ma[y])
ma[y]=++num;
a[x]=y;
update(rt[ma[y]],id[x],,,n);
}
else{
int x(read()),y(read()),z(read());
if(!ma[z])
puts("");
else
printf("%d\n",ask(x,y,z));
}
}
}
[BZOJ 4999]This Problem Is Too Simple!的更多相关文章
- 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 ...
- BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...
- 4999: This Problem Is Too Simple!
Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: C i x(0<=x<2^31) 表示将i节点的值改为x. Q i j x(0<=x<2^31 ...
- 【BZOJ4999】This Problem Is Too Simple!(线段树)
[BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...
- 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA
[BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2 ...
- 【BZOJ】【3489】A simple rmq problem
KD-Tree(乱搞) Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]) ...
- Bzoj 2301: [HAOI2011]Problem b(莫比乌斯反演+除法分块)
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MB Description 对于给出的n个询问,每次求有多少个数对(x, ...
- bzoj 2301: [HAOI2011]Problem b
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MB Submit: 3757 Solved: 1671 [Submit] ...
- BZOJ 2298: [HAOI2011]problem a 动态规划
2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...
随机推荐
- P1491 集合位置 次短路
这个题是一个次短路的裸题,就是把最短路路径求出来之后依次删边,然后跑最短路,在这些情况里取最小值就行了. 题干: 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家 ...
- atoi函数——将字符串转换为整数
atoi在一个叫<cstdlib>的库里,可以把字符串直接转换为整数,贼强势. 还有一个atof,就是换成浮点数,实质上是一样的. 例子: #include<cstdlib> ...
- 枚举详解之EnumSet、EnumMap用法
枚举简单例子 /** * @author shuliangzhao * @Title: Color * @ProjectName design-parent * @Description: TODO ...
- akka监控
使用akka系统时间就了,你就一定会想着监控的事儿.比如某个actor发送了多少消息.接收了多少消息.消息平均处理时间是多少,当前有多少个actor等等.本来我都用bytebuddy写了个简单的akk ...
- MyBatis Generator实现MySQL分页插件
MyBatis Generator是一个非常方便的代码生成工具,它能够根据表结构生成CRUD代码,可以满足大部分需求.但是唯一让人不爽的是,生成的代码中的数据库查询没有分页功能.本文介绍如何让MyBa ...
- 【BZOJ2565】最长双回文串 (Manacher算法)
题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...
- C与C艹的内存管理方式
C 内存开辟出的空间一般可以分成:代码段,数据段(初始化的数据段, 为初始化的数据段BSS),堆,栈 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写 数据段:保存初始化的全局变量 ...
- [转]Linux之ACL权限
转自:http://www.2cto.com/os/201110/108736.html 引言 前面的内容中,我们讲到传统的权限仅有三种身份(owner,group,others)搭配三种权限(r,w ...
- js基础---数字日期及运算
显示年月日 var a=new Date; console.log(a); var year=a.getFullYear(); var month=a.getMonth()+1; var day=a. ...
- python 根据数组生成图片
array = np.asarray(allBigPng, dtype=np.uint8)image = Image.fromarray(array, 'RGBA') image.save(outpu ...