CF1491H Yuezheng Ling and Dynamic Tree(分块)

CF1491H Yuezheng Ling and Dynamic Tree

  • description
  • solution
  • code

description

题目链接

solution

非常清新的小分块题了

前提:将序列分成n\sqrt{n}n块,每块有n\sqrt{n}n个数,记第iii个块的左右边界为Li,RiL_i,R_iLi,Ri,记第iii个数所在块为blockiblock_iblocki

定义topitop_itopi节点iii的祖先中,与iii不在同一个块的最大编号点

【这个真的很妙,可以说是这道题的解法考察点了】

问题是如何在al,ra_{l,r}al,r更新时,对某个块xxx内的被覆盖节点i∈[l,r]i\in[l,r]i[l,r]topitop_itopi进行更新??

  • 如果更新后的ai<Lxa_i<L_xai<Lx,则aia_iai成为新的满足toptoptop定义的最大编号点【iii的祖先都已经全变成了aia_iai的祖先,再加个aia_iai本身】,topi=aitop_i=a_itopi=ai
  • 如果更新后的aia_iai仍然属于块xxx内,则直接链接过去,topi=topaitop_i=top_{a_i}topi=topai

明白了如何维护块内信息,接下来就是对不同块进行操作了

首先考虑修改操作

  • 散块(只覆盖了块内部分点):直接暴力修改点的aia_iai值,然后暴力重构,单次操作时间复杂度O(n)O(\sqrt{n})O(n)

  • 整块:懒标记tagitag_itagi表示点iiiaia_iai还没减多少【比真实的aia_iai多了tagitag_itagi,未真实操作修改】,但这个时候块内某些点的topitop_itopi可能已经发生了变化,没有实时更新就会影响后面的查询操作,而每次暴力修改又需要整个块的遍历,多个整块几乎就是O(O(O(修改区间长度)))的,无法保证时间复杂度

    实际上,发现对于每个块,经过n\sqrt{n}n次整块修改操作后,aia_iai都至少会变为ai−na_i-\sqrt{n}ain一定在当前块前面的块

    因此,我们可以维护每个块被修改的次数cntxcnt_xcntxcntx>ncnt_x>\sqrt{n}cntx>n,就不再暴力修改整块,而是直接整块的区间减法,这个时候的aia_iai一定是其的topitop_itopi,否则就暴力修改

    每个块最多修改n\sqrt{n}n次,每次需要O(n)O(\sqrt{n})O(n)遍历修改,一共有n\sqrt{n}n个块,总时间复杂度是O(nn)O(n\sqrt{n})O(nn)

接着考虑询问操作

lca\text{lca}lca肯定是倍增暴力啦!这里直接使用暴力爬山法

考虑询问u,vu,vu,v两个点的lcalcalca

  • blocku≠blockvblock_u\neq block_vblocku=blockv,则选择对应blockblockblock编号较大的点,跳到其toptoptop

  • blocku=blockvblock_u=block_vblocku=blockvtopu≠topvtop_u\neq top_vtopu=topv,则两个节点一起跳对应的toptoptop

  • blocku=blockvblock_u=block_vblocku=blockvtopu=topvtop_u=top_vtopu=topv,则一直让节点编号大的点跳父亲aaa,直到两点相同为止

    【注意在跳的时候,一定要减去所在块的tagxtag_xtagx标记,才能得到真正的top/atop/atop/a

一个点跳toptoptop的次数最多为nn=n\frac{n}{\sqrt{n}}=\sqrt{n}nn=n次,跳完toptoptop就是在一个块里面的跳aaa,最多也是n\sqrt{n}n次,所以单次询问时间复杂度为O(n)O(\sqrt{n})O(n)

本题最终的时间复杂度为O((n+q)n)O((n+q)\sqrt{n})O((n+q)n)

code

#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100005
#define maxB 320
int n, Q, B, B_cnt;
int a[maxn], block[maxn], L[maxB], R[maxB], cnt[maxB], top[maxn], tag[maxB];void pushup( int x ) {for( int i = L[x];i <= R[x];i ++ ) a[i] = max( 1, a[i] - tag[x] );tag[x] = 0;for( int i = L[x];i <= R[x];i ++ ) {if( a[i] < L[x] ) top[i] = a[i];else top[i] = top[a[i]];}
}void modify( int l, int r, int x ) {if( block[l] == block[r] ) {for( int i = l;i <= r;i ++ ) a[i] = max( 1, a[i] - x );pushup( block[l] );}else {for( int i = l;i <= R[block[l]];i ++ ) a[i] = max( 1, a[i] - x ); pushup( block[l] );for( int i = L[block[r]];i <= r;i ++ ) a[i] = max( 1, a[i] - x ); pushup( block[r] );for( int i = block[l] + 1;i < block[r];i ++ ) {cnt[i] ++, tag[i] = min( n, tag[i] + x );if( cnt[i] <= B ) pushup( i );}}
}int query_top( int i ) { return max( 1, top[i] - tag[block[i]] ); }int query_a( int i ) { return max( 1, a[i] - tag[block[i]] ); }int lca( int x, int y ) {while( 1 ) {if( block[x] < block[y] ) swap( x, y );if( block[x] ^ block[y] ) x = query_top( x );else {if( top[x] ^ top[y] ) x = query_top( x ), y = query_top( y );else break;}}while( x ^ y ) {if( x < y ) swap( x, y );x = query_a( x );}return x;
}int main() {scanf( "%d %d", &n, &Q );B = sqrt( n ), B_cnt = ( n - 1 ) / B + 1;for( int i = 2;i <= n;i ++ ) {scanf( "%d", &a[i] );block[i] = ( i - 1 ) / B + 1;}for( int i = 1;i <= block[n];i ++ ) L[i] = ( i - 1 ) * B + 1, R[i] = min( n, i * B ), pushup( i );for( int i = 1, opt, l, r, x;i <= Q;i ++ ) {scanf( "%d %d %d", &opt, &l, &r );if( opt & 1 ) scanf( "%d", &x ), modify( l, r, x );else printf( "%d\n", lca( l, r ) );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

听说,霸都.NET技术社区准备搞线下聚会了?

.NET Core实战项目交流群日常交流嗨&#xff0c;你听说了没有&#xff1f;霸都.NET技术社区准备搞线下聚会了&#xff01;啥时候的事情啊&#xff1f;最近才知道的消息啊&#xff01;那你是从哪里知道的消息呢&#xff1f;.NET Core项目实战交流群&#xff08;637326624&#x…

Knowledge is Power Gym - 102822K

Knowledge is Power Gym - 102822K 题意&#xff1a; 给你一个数n&#xff0c;让你将n分解成一些互质的数&#xff0c;然后这些数的最大值减最小值要求最小&#xff0c;如果不行输出-1&#xff0c;否则输出最大值减最小值的最小情况 题解&#xff1a; 具体做法是通过枚举大…

P4383 [八省联考 2018] 林克卡特树(wqs二分、树形dp)

解析 它还真的不难。 乐。 这题没做出来有些谔谔。 外层wqs二分显而易见&#xff0c;里面不知道为啥我总觉得这个题可以贪心。 然后一直试图在原树直径上下功夫&#xff0c;一筹莫展。 看到题解“dp”两个字这题也就做完了… 就相当于要把一棵树分成若干条无交链&#xff0c;每…

ASP.NET Core中实现单体程序的事件发布/订阅 - LamondLu - 博客园

标题&#xff1a;ASP.NET Core中实现单体程序的事件发布/订阅作者&#xff1a;Lamond Lu地址&#xff1a;https://www.cnblogs.com/lwqlun/p/10468058.html项目源代码&#xff1a;https://github.com/lamondlu/EventHandlerInSingleApplication背景事件发布/订阅是一种非常强大…

CF1592E Bored Bakry(二进制+前缀异或和)

CF1592E Bored Bakrydescriptionsolutioncodedescription 题目链接 solution and\text{and}and如果第iii位为111&#xff0c;意味着区间内每个数的第iii位都是111 xor\text{xor}xor如果第iii位为111&#xff0c;意味着区间内有奇数个第iii位为111 这种涉及二进制操作的一般都…

Joy of Handcraft Gym - 102822J(线段树或差分)

Joy of Handcraft Gym - 102822J 题意&#xff1a; 每个灯有亮的周期和亮度&#xff0c;问1~m这段时间灯光最亮是多少 题解&#xff1a; 线段树维护区间最大值 根据灯的周期向这段区间加亮度k&#xff0c;然后利用线段树维护区间最大值 但是这样会超时&#xff0c;加个小优…

.NET Core 使用 HttpClient SSL 请求出错的解决办法

问题使用 HTTP Client 请求 HTTPS 的 API 时出现 The certificate cannot be verified up to a trusted certification authority 异常&#xff0c;并且证书已经传入。下面就是问题代码&#xff1a;public class Program{public static void Main(string[] args){var url &quo…

CF1580C Train Maintenance(分块)

CF1580C Train Maintenancedescriptionsolutioncodedescription 题目链接 solution 这是一种利用根号平衡时间复杂度的套路 分α\alphaα【操作参数】与n\sqrt{n}n​的关系&#xff0c;一半采取暴力&#xff0c;一半利用工具特殊处理 对于本题&#xff0c;假设第iii辆车的加…

P3746 [六省联考 2017] 组合数问题(倍增、dp)

解析 再次被“组合数问题”吊打qwq 和上一次不一样的是&#xff0c;这次更加被恶心到了。 一方面受上一个组合数问题影响&#xff0c;另外出题人也十分阴间&#xff0c;一开始还给了个组合数的公式&#xff0c;更加使我坚定的认为这是一道数学推柿子题。 然后就开始各种打表玩…

CF1473E Minimum Path(拆点+最短路)

CF1473E Minimum Pathdescriptionsolutioncodedescription 题目链接 solution 看到 ∑i1kwei\sum_{i1}^kw_{e_i}∑i1k​wei​​ 的式子&#xff0c;就应该联想到最短路 先考虑题目的弱化版&#xff0c;去掉 max,min\text{max},\text{min}max,min 的限制&#xff0c;变成一条…

2020CCPC绵阳

2020CCPC绵阳 题号题目名难度知识点AA Colorful GridBBuilding BlocksCCode a TrieDDefuse the Bombs签到二分EEscape from the IslandFFracture RayGGame of Cards银牌博弈论&#xff0c;SG函数HHide and SeekIInvaluable AssetsJJoy of Handcraft快铜线段树KKnowledge is Po…

P3747 [六省联考 2017] 相逢是问候(欧拉定理、线段树、光速幂)

解析 洛谷你恶事做尽&#xff01; 第三个tag在LOJ、bzoj等都是不需要的… 但在洛谷三只log根本过不去… 我谔谔。 如果做过 上帝与集合的正确用法 &#xff0c;那么本题就并不难了。 打个表就可以发现&#xff0c;不断取欧拉函数的上限只有log级别&#xff0c;这使得我们暴力…

Lottery Gym - 102822L

Lottery Gym - 102822L 题意&#xff1a; 有n个盒子&#xff0c;每个盒子有x个球&#xff0c;每个球的数值为2a,问最多能组成多少数&#xff1f;答案mod 1e97 题解&#xff1a; 二进制思维题&#xff0c;浓浓的cf风格 参考题解 我们将数按照幂次进行排序&#xff08;从小到…

[CCO 2019] Sirtet(差分约束+最短路)

[CCO 2019] Sirtetdescriptionsolutioncodedescription 题目链接 solution 很巧妙地将差分约束隐藏起来 问题的关键在于求出每一个sand停止运动的时间&#xff0c;这样很容易填涂出最后的答案&#xff08;向下平移即可&#xff09; 不妨设 ti,jt_{i,j}ti,j​ 表示 (i,j)(i…

P3748 [六省联考 2017] 摧毁“树状图”(树形dp)

Foreword\text{Foreword}Foreword 《小清新》树形 dp。 其实本题没有那么&#xff08;重读&#xff09;恶心&#xff0c;但我一开始写完 x0x0x0 后眼瞎没有看到 x1,2x1,2x1,2 时也必然是最优方案&#xff08;这种东西不黑体吗…&#xff09;可以直接无视&#xff0c;还在苦苦的…

微软4年后重登市值第一,纳德拉如何做到的?

他用4年多时间将微软的市值提高了5000亿美元&#xff0c;超越苹果再次成为全球市值最高的上市公司。译 | 达达萨提亚纳德拉&#xff08;Satya Nadella&#xff09;2014年刚刚执掌微软时&#xff0c;微软当时是一个日渐没落的帝国。但在他领导的4年多时间里&#xff0c;微软百花…

[AtCoder Regular Contest 124E] Pass to Next(dp+数学)

ARC 124 E Pass to Nextproblemsolutioncodeproblem 题目链接 solution 令 ci:c_i:ci​: 第 iii 个人传给下一个人球的个数 当 min⁡{ci}≠0\min\{c_i\}\neq 0min{ci​}​0 时&#xff0c;将每一个 cic_ici​ 都减小 111&#xff0c;显然答案序列并不会改变 所以&#x…

P2015 二叉苹果树

P2015 二叉苹果树 题意&#xff1a; 一个完全二叉树&#xff0c;n个点&#xff0c;n-1个边&#xff0c;每个边都有边权&#xff0c;问保留q个边&#xff0c;所能保留的最大边权是多少 题解&#xff1a; 树形dp dp[u][i]表示u的子树上保留i条边&#xff0c;至多保留的苹果数…

P4384 [八省联考 2018] 制胡窜(SAM)

Foreword\text{Foreword}Foreword 人都道正难则反&#xff0c;我偏说正也不难。 这里介绍一种正面直接统计的做法。 和补集做法相比&#xff0c;没有那么多的分类讨论&#xff0c;更多的是对问题的正向分析和逐层化简、转化&#xff0c;也并不麻烦。 由于需要写很多线段树的操作…

【.NET Core项目实战-统一认证平台】第十五章 网关篇-使用二级缓存提升性能

首先说声抱歉&#xff0c;可能是因为假期综合症&#xff08;其实就是因为懒哈&#xff09;的原因&#xff0c;已经很长时间没更新博客了&#xff0c;现在也调整的差不多了&#xff0c;准备还是以每周1-2篇的进度来更新博客&#xff0c;并完成本项目所有功能。言归正传&#xff…