Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间
一看就知道 可以LCA判断做 也可以树链剖分拿头暴力
然而快速读入和线段树维护区间会T70 于是只能LCA?
线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组
这个题的代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define pb push_back int n , qn ;
vector<int > q [100050] ;
int top[100050] , fa[100050] , deep[100050] , num[100050] , p[100050] , fp[100050] , son[100050] , pos ; inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
} ///---------- int c[100050] ;
int d[100050] ;
int lowbit(int x) {
return (x & (-x)) ;
}
void add(int c[] , int x ,int val) {
while(x <= n+5) {
c[x] += val ; x += lowbit(x) ;
}
}
int sum(int c[] , int x) {
int res = 0 ;
while(x > 0) {
res += c[x] ;
x -= lowbit(x) ;
}
return res ;
}
void add(int l , int r , int val) {
add(c , l , val) ; add(d , l , l * val) ;
add(c , r+1 , -val ) ; add(d , r + 1 , -val * (r+1)) ;
}
int sum(int x) {
return (x + 1) * sum(c , x) - sum(d , x) ;
}
int sum(int l , int r) {
return sum(r) - sum(l - 1) ;
} ///---------- void dfs1(int u , int pre , int d) {
deep[u] = d ;
fa[u] = pre ;
num[u] = 1 ;
for(int i = 0 ; i < q[u].size() ; i ++ ) {
int v = q[u][i] ;
if(v != pre) {
dfs1(v , u , d+1) ;
num[u] += num[v] ;
if(son[u] == -1 || num[v] > num[son[u]]) {
son[u] = v ;
}
}
}
}
void getpos(int u , int sp) {
top[u] = sp ;
p[u] = pos ++ ;
fp[p[u]] = u ;
if(son[u] == -1) return ;
getpos(son[u] , sp) ;
for(int i = 0 ; i < q[u].size() ; i ++ ) {
int v = q[u][i] ;
if(v != son[u] && v != fa[u]) {
getpos(v , v) ;
}
}
}
void chang(int u , int v , int val) {
int f1 = top[u] , f2 = top[v] ;
int tmp = 0 ;
while(f1 != f2) {
if(deep[f1] < deep[f2]) {
swap(f1 , f2) ; swap(u , v) ;
}
add(p[f1] , p[u] , val) ;
u = fa[f1] ;
f1 = top[u] ;
}
if(deep[u] > deep[v]) swap(u , v) ;
add(p[u] , p[v] , val) ;
}
int que(int u , int v) {
int f1 = top[u] , f2 = top[v] ;
int tmp = 0 ;
while(f1 != f2) {
if(deep[f1] < deep[f2]) {
swap(f1 , f2) ; swap(u , v) ;
}
tmp += sum(p[f1] , p[u]) ;
u = fa[f1] ;
f1 = top[u] ;
}
if(deep[u] > deep[v]) swap(u , v) ;
tmp += sum(p[u] , p[v]) ;
return tmp ;
} int main () {
n = read() ;
qn = read() ;
for(int i = 2 ; i <= n ; i ++ ) {
int z ; z = read() ;
q[z].pb(i) ; q[i].pb(z) ;
}
memset(son , -1 , sizeof(son)) ;
pos = 1 ;
dfs1(1,0,0) ;
getpos(1 , 1) ;
while(qn -- ) {
int aa , bb , cc ;
aa = read() ; bb = read() ; cc = read() ; int ans = 0 ; chang(aa,bb,1) ;
ans = max(que(bb,cc) , ans) ;
chang(aa,bb,-1) ; chang(aa,cc,1) ;
ans = max(que(bb,cc) , ans) ;
chang(aa,cc,-1) ; chang(aa,bb,1) ;
ans = max(que(aa,cc) , ans) ;
chang(aa,bb,-1) ; printf("%d\n" , ans) ;
}
}
其中的树状数组 拿两个数组来分别维护 具体代码
int c[100050] ;
int d[100050] ;
int lowbit(int x) {
return (x & (-x)) ;
}
void add(int c[] , int x ,int val) {
while(x <= n+5) {
c[x] += val ; x += lowbit(x) ;
}
}
int sum(int c[] , int x) {
int res = 0 ;
while(x > 0) {
res += c[x] ;
x -= lowbit(x) ;
}
return res ;
}
void add(int l , int r , int val) {
add(c , l , val) ; add(d , l , l * val) ;
add(c , r+1 , -val ) ; add(d , r + 1 , -val * (r+1)) ;
}
int sum(int x) {
return (x + 1) * sum(c , x) - sum(d , x) ;
}
int sum(int l , int r) {
return sum(r) - sum(l - 1) ;
}
树状数组天下无敌TAT 于是又上网学习了新姿势 我有姿势我自豪
树状数组单点修改 + 区间查询max
int num[5000] ;
int c[5000] ;
int n ;
int lowbit(int x)
{
return x & (-x);
}
void updata(int x)
{
int lx, i;
while (x <= n)
{
c[x] = num[x];
lx = lowbit(x);
for (i=1; i<lx; i<<=1)
c[x] = max(c[x], c[x-i]);
x += lowbit(x);
}
}
int query(int L, int R)
{
int ans = 0;
while (R >= L)
{
ans = max(num[R], ans);
R --;
for (; R-lowbit(R) >= L; R -= lowbit(R))
ans = max(c[R], ans);
}
return ans;
}
以及这里还有...矩形增减 + 矩形查询和的黑科技。。。
http://blog.csdn.net/lawrence_jang/article/details/8054173
Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间的更多相关文章
- Codeforces Round #425 (Div. 2) D.Misha, Grisha and Underground
我奇特的脑回路的做法就是 树链剖分 + 树状数组 树状数组是那种 区间修改,区间求和,还有回溯的 当我看到别人写的是lca,直接讨论时,感觉自己的智商收到了碾压... #include<cmat ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
- bzoj 2819 Nim dfn序+树状数组维护区间异或值
题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分
D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...
- Codeforces Round #425 (Div. 2) - D
题目链接:http://codeforces.com/contest/832/problem/D 题意:给定一棵n个点的树,然后给你q个询问,每个询问为三元组(a,b,c),问你从这三个点中选取一个作 ...
随机推荐
- TP【连接数据库配置及Model数据模型层】
[连接数据库配置及Model数据模型层] convertion.php config.php 在config.php做数据库连接配置 制作model模型 a) model本身就是一个类文件 b) 数据 ...
- 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集
[BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...
- <2013 08 17> BucketList of girlfriend
BucketList of girlfriend 1.出国旅游 2.跟相爱的人结婚,生个健康可爱的孩子 3.说一口流利的英语 4.学素描和水彩 5.买个雅马哈钢琴,偶尔学着弹一首曲子 6.把泪腺堵住 ...
- linux下安装mysql问题总结(一)mysqld_safe mysqld from pid file /usr/local/mysql/data/mysql.pid ended
linux下安装mysql数据库 linux版本:CentOS release 6.8 (Final) mysql版本:mysql-5.7.16-linux-glibc2.5-x86_64.tar.g ...
- Python 是怎么火起来的?
Python 之父 Guido 正在设计 Python 语言,结果家里突然潜入一条大蟒蛇,一番激烈斗争,大蟒蛇把 Guido 叔生吞进肚,并洋洋自得:So Who is Guido Van Rossu ...
- 《Python机器学习》笔记(三)
使用scikit-learning 实现机器学习分类算法 分类算法的选择 没有免费的午餐理论:没有任何一种分类器可以在所有可能的应用场景下都有良好的表现. 实践证明,只有比较了多种学习算法的性能,才能 ...
- Java并发—简介与线程创建
程序.进程和线程 程序:一段静态的代码,一组指令的有序集合,不运行的话只是一堆代码. 程序并不能单独执行,只有将程序加载到内存中,系统为他分配资源后才能够执行,这种执行的程序称之为进程.也就是说进程是 ...
- 1.2 使用电脑测试MC20模块的GPS功能测试
需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...
- numpy的通用函数:快速的元素级数组函数
通用函数(ufunc)是对ndarray中的数据执行元素级运算的函数.可看作简单函数的矢量化包装. 一元ufunc sqrt对数组中的所有元素开平方 exp对数组中的所有元素求指数 In [93]: ...
- c#读取xml操作
1/定义一个XmlDocument对象xDoc 2/通过XmlDocument来load需要读取的xml文件 3/通过XmlDocument的SelectSingleNode来找到节点,并把节点转换为 ...