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),问你从这三个点中选取一个作 ...
随机推荐
- jQuery倒计时实例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Server Objects Extension(SOE)开发(二)
前言 SOE的提供了REST和Soap两种模板,只要在模板特定的方法中添加自己的业务逻辑代码即可,开发流程非常的简单便捷.那怎么知道自己的业务逻辑代码该写在模板的那个方法里面呢?这就需要很好的理解SO ...
- 在Tomcat配置JNDI数据源的三种方式
最近使用到了在tomcat下配置数据源的内容,在这里转载一篇文章记录下 转载自: http://blog.csdn.net/dyllove98/article/details/7706218 在我过去 ...
- Django 视图系统(views)
介绍 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图 ...
- 数据库之MySQL(三)
视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 临时表搜索 SELECT *FRO ...
- [置顶] 我的Android进阶之旅------>Android解决异常: startRecording() called on an uninitialized AudioRecord.
今天使用AudioRecord进行录音操作时候,报了下面的异常. E/AndroidRuntime(22775): java.lang.IllegalStateException: startReco ...
- locust基本使用
# coding:utf-8 from locust import HttpLocust,TaskSet,task class BlogDemo(TaskSet): '''用户行为:打开我的博客首页d ...
- java中参数传递的问题
public class Test { public static void main(String[] args) { StringBuffer a = new StringBuffer(" ...
- studio显示Surface: getSlotFromBufferLocked: unknown buffer: 0xa2a58be0
根据查询外网资料来看,出现这个错误的原因大致是换个模拟器或者物理机就可以了. 因为我使用的是安卓6.0,貌似都会出现这类的问题. 但是不影响程序运行.
- cqlsh script
1.time类型 cqlsh> COPY my_keyspace.typetest from STDIN;Using 1 child processes Starting copy of my_ ...