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),问你从这三个点中选取一个作 ...
随机推荐
- node.js调用函数
首先EditPlus编辑器,打开新建的文本文档,另存为副本 调用函数分为调用本地函数,和其他文件的函数 1.调用本地函数 var http = require('http'); http.create ...
- node.js的安装与第一个hello world、node.js的初始化
1.下载node.js文件 2.windows下点击安装 重复下一步即可 3.编辑工具 EditPlus编辑器 4.新建保存目录的文件夹,并新建一个文本文档 5.打开EditPlus编辑器 打开 ...
- 【转】IBM PowerVM虚拟化技术笔记
1. 从CPU虚拟化的角度, 分区(partition)可以分成两大类:Micro-partition和Dedicated-procesor.前者可以将物理处理器以0.01的 粒度分配给微分区,分区创 ...
- MySQL中哈希表
也称为散列表 由直接寻址表改进而来.先看直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.加入某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,...,m-1}的 ...
- .Net自带ChartControl报错:Auto interval does not have proper value
出现这个错误的原因是我们给ChartControl同时设置了Minimum和Maxmum的值,而这两个值又恰好相等. chart.ChartAreas[0].AxisY.Minimum=min; ch ...
- Version 1.5 of the JVM is not suitable for this product.Version:1.6 or greater is required
近期在公司涉及到了服务器等的扩展,smartfoxserver扩展使用的Eclipse,尽管没学过java.可是咱毕竟是C++起价的,其它语言看看也就会了,项目依然做着,近期看到某同学有一些java的 ...
- SMARTFORM 传值的4种方法
*& 20161019 160300 smartform传值的方法 1.通过结构 传值: 最通常的用法是通过SE11中建立STRUCTURE XXX(表则没用),在REPORT中申明此结构的数 ...
- Shell字符串操作
@1:子串削除 ${string#substring} 从$string 的开头位置截掉最短匹配的$substring. ${string##substring} 从$string 的开头位置截掉最长 ...
- List Slice in Python(Compared with Java)
Python: 在Python中, 对于list, 切片会返回一个新的list, 而不会改变原有的list. 注意这儿说的"不会改变原有的list"指的是下面的这种情况: a = ...
- Dancing Link专题
一些链接: http://www.cnblogs.com/-sunshine/p/3358922.html http://www.cnblogs.com/grenet/p/3145800.html 1 ...