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),问你从这三个点中选取一个作 ...
随机推荐
- 如何将大数据保存到 MySql 数据库
1. 什么是大数据 1. 所谓大数据, 就是大的字节数据,或大的字符数据. 2. 标准 SQL 中提供了如下类型来保存大数据类型: 字节数据类型: tinyblob(256B), blob(64K), ...
- 一、Nuxt简介
1.Nuxt是什么 Nuxt.js是基于vue的服务器端渲染框架,常用来做SSR(服务器端渲染) 2.为什么用Nuxt Vue开发的SPA(单页应用)不利于搜索引擎的SEO优化 3 ...
- 父标签浮动(float)“塌陷”问题
浮动“塌陷” float参见: http://www.cnblogs.com/bigtreei/p/8110090.html http://www.w3school.com.cn/css/css_po ...
- python cookbook第三版学习笔记二十一:利用装饰器强制函数上的类型检查
在演示实际代码前,先说明我们的目标:能对函数参数类型进行断言,类似下面这样: @typeassert(int, int) ... def add(x, y): ... return x + y ...
- (4.13)SQL Server profile使用、数据库优化引擎顾问使用
SQL Server profile使用技巧 介绍 经常会有人问profile工具该怎么使用?有没有方法获取性能差的sql的问题.自从转mysql我自己也差不多2年没有使用profile,忽然prof ...
- Longest Common Prefix -最长公共前缀
问题:链接 Write a function to find the longest common prefix string amongst an array of strings. 解答: 注意 ...
- JavaWeb—过滤器Filter
1.Filter简介 Filter称之为过滤器,是用来做一些拦截的任务.比如客户端请求服务器的某个资源时(可以是Servlet.JSP.HTML等等),我们可以拦截.当服务器返回资源给客户端的时候,我 ...
- mysql启动报错“NET HELPMSG 3534“的解决办法
原因: mysql安装步骤错误,从mysql5.7.6开始,mysql需要这样安装: mysqld --initialize-insecure或者mysqld --initialize mysqld ...
- PictureBox 双缓冲防止闪屏
Bitmap bm = new Bitmap(this.pbTraffic.Image); BufferedGraphicsContext current = BufferedGraphicsMana ...
- 前端 css续
CSS选择器 1.标签选择器 为类型标签设置样式例如:<div>.<a>.等标签设置一个样式,代码如下: <style> /*标签选择器,找到所有的标签应用以下样式 ...