【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
题目描述
输入
输出
样例输入
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 30
样例输出
0
1
1
0
题解
树链剖分+动态开点线段树
对树轻重链剖分,对每个权值开一棵动态开点线段树,修改时相当于删除再加入,查询时直接查询链上信息即可。
时间复杂度$O(m\log^2n)$,有更优秀的$O((m+n)\log n)$解法,但在本题中好像没什么必要= =
#include <map>
#include <cstdio>
#include <algorithm>
#define N 100010
#define lson l , mid , ls[x]
#define rson mid + 1 , r , rs[x]
using namespace std;
map<int , int> mp;
int a[N] , head[N] , to[N << 1] , next[N << 1] , cnt , fa[N] , deep[N] , si[N] , bl[N] , pos[N] , num;
int root[N << 2] , ls[N << 7] , rs[N << 7] , sum[N << 7] , tot , n , clo;
char str[5];
void add(int x , int y)
{
to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void dfs1(int x)
{
int i;
si[x] = 1;
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x])
fa[to[i]] = x , deep[to[i]] = deep[x] + 1 , dfs1(to[i]) , si[x] += si[to[i]];
}
void dfs2(int x , int c)
{
int i , k = 0;
bl[x] = c , pos[x] = ++num;
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x] && si[to[i]] > si[k])
k = to[i];
if(k)
{
dfs2(k , c);
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x] && to[i] != k)
dfs2(to[i] , to[i]);
}
}
void update(int p , int a , int l , int r , int &x)
{
if(!x) x = ++tot;
sum[x] += a;
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) update(p , a , lson);
else update(p , a , rson);
}
int query(int b , int e , int l , int r , int x)
{
if(!x) return 0;
if(b <= l && r <= e) return sum[x];
int mid = (l + r) >> 1 , ans = 0;
if(b <= mid) ans += query(b , e , lson);
if(e > mid) ans += query(b , e , rson);
return ans;
}
int solve(int x , int y , int c)
{
int ans = 0;
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]]) swap(x , y);
ans += query(pos[bl[x]] , pos[x] , 1 , n , root[c]) , x = fa[bl[x]];
}
if(deep[x] > deep[y]) swap(x , y);
ans += query(pos[x] , pos[y] , 1 , n , root[c]);
return ans;
}
int main()
{
int m , i , x , y , z;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]);
for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
dfs1(1) , dfs2(1 , 1);
for(i = 1 ; i <= n ; i ++ )
{
if(!mp[a[i]]) mp[a[i]] = ++clo;
update(pos[i] , 1 , 1 , n , root[mp[a[i]]]);
}
while(m -- )
{
scanf("%s%d%d" , str , &x , &y);
if(str[0] == 'C')
{
update(pos[x] , -1 , 1 , n , root[mp[a[x]]]);
if(!mp[y]) mp[y] = ++clo;
update(pos[x] , 1 , 1 , n , root[mp[y]]);
a[x] = y;
}
else
{
scanf("%d" , &z);
if(!mp[z]) puts("0");
else printf("%d\n" , solve(x , y , mp[z]));
}
}
return 0;
}
【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树的更多相关文章
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...
- [ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)
首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数.然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树.最后再从根节点开始做一遍dfs, ...
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- bzoj3531——树链剖分+动态开点线段树
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MB Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连 ...
- [LuoguU41039]PION后缀自动机 树链剖分+动态开点线段树
链接 刚开始看出题人题解都吓蒙掉了,还以为是什么难题,结果就一板子题 思路:对每一个文件名开一棵线段树,然后树剖即可 #include<bits/stdc++.h> #define REP ...
随机推荐
- Ubuntu中文乱码问题
版本 Ubuntu 14.1 系统安装完成后,中文都显示成了乱码 终端或者命令行里输入 sudo apt-get install zhcon 等安装完即可~ 运行的时候记得要加载vgz驱动和utf8支 ...
- python操作文件目录
# 查看当前目录的绝对路径: >>> os.path.abspath('.') /Users/NaCl/Documents/GitHub #同样的道理,要拆分路径时,也不要直接去拆字 ...
- vue.js 一(基础环境搭建)
之前由于看了React的东西,写了两篇React的脚手架搭建,一是给自己记一点可用的东西,免得每次都去找,毕竟搭建环境在项目相对固定的时期不是经常要干的事情,一段时间不用就会忘记了. 前端的js框架还 ...
- JavaScriptDate(日期)
如何使用Date()方法获取当日的日期. getFullYear(): 使用getFullYear()获取年份. getTime(): getTime()返回1970年1月1日至今的毫秒数. setF ...
- 【php】session_start 报 no such file
如果是yum安装修改php-fpm.conf 里面的 session.save_path 如果是编译的,修改php.ini 的session.save_path (此条未测试)
- Matlab数据转化至python端,并写入数据库
因工作原因,一些获取的行业数据以已知的结构体存储在.mat文件中, 现需要将其存储在数据库中并且能够灵活调用至python dataframe里进行操作 原数据的一个例子如下 目标如上: 然后是转化代 ...
- CMDB(资产管理系统) day1
运维自动化最重要的就是标准化一切 自动化运维则支持以下功能: 1.OS的选择统一化,同一个项目使用同样的OS系统部署其所需要的各类软件.2.软件安装标准化,例如JAVA虚拟机,php,nginx,my ...
- GoF23种设计模式之创建型模式之抽象工厂模式
一.概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 二.适用性 1.一个系统要独立于它的产品的创建.组合和表示的时候. 2.一个系统要由多个产品系列中的一个来配置的时候. ...
- 【Akroma, Angel of Fury】完成svn环境搭建
昨天的那篇博文恰恰是实验室所干的事儿 但是那是一种很投机取巧的方式完成的多project管理方式 来看看我建立环境的方法 首先,找一个比较闲的公用服务器(为什么不用自己的?有公共资源不用,你傻啊?), ...
- RCP 主题切换
第一步 编写css文件,放到项目目录下 第二步 添加切换主题扩展点 第三步 设置主题 public void switchTheme(String themeID) { Bu ...