[cf1491H]Yuezheng Ling and Dynamic Tree
将其按照区间分块(即$[(i-1)K+1,iK]$作为一个块),并定义$f_{x}$表示$x$的祖先中编号最小且与$x$在同一个块内的节点,$f_{x}$可以通过$f_{a_{x}}$转移,即$f_{x}=\begin{cases}f_{a_{x}}\ \ \ (x与a_{x}在一个块中)\\x\ \ \ \ \ \ (x与a_{x}不在一个块中)\end{cases}$
(特别的,若$x$在第一个块中则$f_{x}=1$)
通过$f_{x}$,类似于树剖的方式,即若两者$f_{x}$不同则移动$f_{x}$较大的(移动到$f_{x}$),直至相同再用同样的方式爬$a_{x}$,复杂度显然是$o(q\sqrt{n})$的
接下来是如何维护$f_{x}$,即如何支持修改:
对于边角的两个块,显然是可以暴力维护的,对于整块修改,显然当一个块被修改$\sqrt{n}$次后一定有$f_{x}=x$,因此至多$o(n)$次暴力,复杂度也是$o(n\sqrt{n})$
最终总复杂度即为$o((n+q)\sqrt{n})$


- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 #define N 100005
- 4 int n,m,K,p,x,y,z,a[N],bl[N],st[N],ed[N],f[N];
- 5 long long tag[N];
- 6 int get(int k){
- 7 return max(a[k]-tag[bl[k]],1LL);
- 8 }
- 9 void calc(int x,int y){
- 10 for(int i=x;i<=y;i++)
- 11 if (bl[i]==1)f[i]=1;
- 12 else{
- 13 int x=get(i);
- 14 if (bl[x]!=bl[i])f[i]=i;
- 15 else f[i]=f[x];
- 16 }
- 17 }
- 18 int main(){
- 19 scanf("%d%d",&n,&m);
- 20 for(int i=2;i<=n;i++)scanf("%d",&a[i]);
- 21 K=(int)sqrt(n);
- 22 for(int i=1;i<=n;i++)bl[i]=(i-1)/K+1;
- 23 for(int i=1;i<=bl[n];i++){
- 24 st[i]=(i-1)*K+1;
- 25 ed[i]=min(i*K,n);
- 26 calc(st[i],ed[i]);
- 27 }
- 28 calc(1,n);
- 29 for(int i=1;i<=m;i++){
- 30 scanf("%d%d%d",&p,&x,&y);
- 31 if (p==1){
- 32 scanf("%d",&z);
- 33 if (bl[x]==bl[y]){
- 34 for(int j=x;j<=y;j++)a[j]=max(a[j]-z,1);
- 35 calc(st[bl[x]],ed[bl[x]]);
- 36 }
- 37 else{
- 38 for(int j=x;j<=ed[bl[x]];j++)a[j]=max(a[j]-z,1);
- 39 calc(st[bl[x]],ed[bl[x]]);
- 40 for(int j=st[bl[y]];j<=y;j++)a[j]=max(a[j]-z,1);
- 41 calc(st[bl[y]],ed[bl[y]]);
- 42 for(int j=bl[x]+1;j<=bl[y]-1;j++){
- 43 tag[j]+=z;
- 44 if (tag[j]-z<=K)calc(st[j],ed[j]);
- 45 }
- 46 }
- 47 }
- 48 else{
- 49 while (f[x]!=f[y]){
- 50 if (f[x]>f[y])swap(x,y);
- 51 y=get(f[y]);
- 52 }
- 53 if (x==y){
- 54 printf("%d\n",x);
- 55 continue;
- 56 }
- 57 while (get(x)!=get(y)){
- 58 if (get(x)>get(y))swap(x,y);
- 59 y=get(y);
- 60 }
- 61 if (x==y)printf("%d\n",x);
- 62 else printf("%d\n",get(x));
- 63 }
- 64 }
- 65 }
[cf1491H]Yuezheng Ling and Dynamic Tree的更多相关文章
- Codeforces 1491H - Yuezheng Ling and Dynamic Tree(分块)
Codeforces 题目传送门 & 洛谷题目传送门 *3400 的毒瘤 H 题,特意写个题解纪念一下( 首先对于这种数据结构不太好直接维护的东东可以考虑分块.然鹅我除了分块其他啥也没想到 我 ...
- Solution -「CF 1491H」Yuezheng Ling and Dynamic Tree
\(\mathcal{Description}\) Link. 做题原因:题目名. 给定一个长度 \(n-1\) 的序列 \(\{a_2,a_3,\cdots,a_n\}\),其描述了一棵 \ ...
- 10+ 最流行的 jQuery Tree 菜单插件
jstree – jQuery Tree Plugin With HTML & JSON Data jstree is a lightweight and flexible jQuery pl ...
- java基础十[包、Jar存档文件和部署](阅读Head First Java记录)
将Java的class文件生成为可执行的Java应用程序.Java应用程序有三种:完全在本机执行的Jar(例如本机的GUI可执行程序):完全在服务器端远程执行的(例如浏览器来进行存取):介于两者之间的 ...
- FTP客户端上传下载Demo实现
1.第一次感觉MS也有这么难用的MFC类: 2.CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归),采用队列存储目录再依次下载: 3.本程序支持文件夹嵌套上传下载: ...
- [ActionScript 3.0] Away3D 官网实例
/* Dynamic tree generation and placement in a night-time scene Demonstrates: How to create a height ...
- PeopleCode事件和方法只用于online界面不能用于组件接口(component interface)
在使用CI过程中,哪些方法是不能使用的.以下为PeopleBook解释的内容. 一.搜索框代码不执行:SearchInit, SearchSave, and RowSelect events 意味着使 ...
- table2excel使用
原table2excel代码 /* * 采用jquery模板插件——jQuery Boilerplate * * Made by QuJun * 2017/01/10 */ //table2excel ...
- dhtmlxtree 如何得到xml,json等文件中的自定义的属性值
先看代码: var TreeForJSON = new dhtmlXTreeObject('TreeForJSON', '100%', '100%', 0); TreeForJSON.setImage ...
随机推荐
- 第21篇-加载与存储指令之iload、_fast_iload等(3)
iload会将int类型的本地变量推送至栈顶.模板定义如下: def(Bytecodes::_iload , ubcp|____|clvm|____, vtos, itos, iload , _ ); ...
- 洛谷4400 BlueMary的旅行(分层图+最大流)
qwq 首先,我们观察到题目中提到的每天只能乘坐一次航班的限制,很容易想到建分层图,也就是通过枚举天数,然后每天加入一层新的点. (然而我一开始想的却是erf) 考虑从小到大枚举天数,然后每次新建一层 ...
- Spring Boot 整合 Apache Ignite
关于Ignite的介绍,这边推荐三个链接进行学习了解. https://ignite.apache.org/,首选还是官网,不过是英文版,如果阅读比较吃力可以选择下方两个链接. https://www ...
- 实现前后端分离,最好的方案就是SPA(Single Page Application)
从通常意义来讲,说到必须,就是指最佳实践上,实现前后端分离,最好的方案就是SPA.所以才会有 前后端分离=SPA 的近似,忽视了其中的差别.但是,既然有疑问了,我们就来看一下,为什么SPA是实现前后端 ...
- Kubernetes List-Watch 机制原理与实现 - chunked
概述http chunkedwatch api 概述 Kubernetes 中主要通过 List-Watch 机制实现组件间的异步消息通信,List-Watch 机制的实现原理值得深入分析下 . 在 ...
- Flask聚合函数(基本聚合函数、分组聚合函数、去重聚合函数))
Flask聚合函数 1.基本聚合函数(sun/count/max/min/avg) 使用聚合函数先导入:from sqlalchemy import func 使用方法: sun():func.sum ...
- leetcode779 第k个语法符号。
直接找规律. 第一行 0 第二行 01 第三行 0110 第四行 01101001 可以发现,第n行的数量比第n-1行多了一倍,并且前半部分是和第n-1行一样的,后半部分是前半部分"按位取反 ...
- JDK 8中重要的函数式接口(必知必会)
JDK 8 提供的重要函数式接口: Consumer (消费者) 功能:接收一个对象,返回void. 定义:void accept(T t) 默认方法:Consumer andThen(Consume ...
- 改善深层神经网络-week1编程题(Initializaion)
Initialization 如何选择初始化方式,不同的初始化会导致不同的结果 好的初始化方式: 加速梯度下降的收敛(Speed up the convergence of gradient desc ...
- react 生命周期 个人见解
初始化/实例期 gitDefaultprops 获取组件的默认props状态 gitInitialstate 类定义方式或是直接在构造函数中挂载state componentWillMount 组件 ...