![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
莫队
code到飞起
这个作者很懒,什么都没留下…
展开
-
H. Yuezheng Ling and Dynamic Tree
给出一颗树,知道节点i的父亲是a[i],并保证了a[i]<i。给出n个询问:1. l,r区间的节点的a[i] = max(a[i]-x,1)2.问lca(u,v)由于a[i]<i,那么节点和父亲就是有序了。由于是区间询问,可以用莫队分块。按sqrt(n)分块后,记录每个节点到块的最小节点 f(i) = f(a[i])。这样就相当于把一颗树缩成了sqrt(n)个节点的树了。更新的时候,对于[l,r]区间,如果是同一个块,则暴力(sqrt(n)),如果不是同一个块..原创 2021-05-20 04:18:11 · 104 阅读 · 0 评论 -
D. Odd Mineral Resource
由于是统计树上某个区间的值,因此就是树上莫队了。套个树上莫队的模板先。。。对树上的区间进行排序,然后更新的时候判断一下更新的节点是奇还是偶,放进cnt数组里面。然后问题来了。查询的是对cnt数组的一个区间进行查询,那么这里就需要用到树状数组去二分了。这样在修改的时候就多了一个log,这样就T了。所以不能对修改做任何扩展,只能修改查询部分。继续使用分块思想。对cnt数组去分组。然后查询的时候一组一组去查询,如果组内有数据,就直接暴力返回结果。一共有sqrt(n)个组,组..原创 2021-04-21 18:53:44 · 125 阅读 · 0 评论 -
[Ynoi2016] 掉进兔子洞
给出一个序列,和m个查询。每一个查询有3个区间,问3个区间去掉相同的数字后,一共有多少个数字。利用bitset的集合交来查询。b1&b2&b3可以统计3个区间一共有多少个相同数字。对于某个数字i,在序列里面出现了k次,那么他就占了k位。这种可以通过离散化重新分配id来实现。 fr(i,1,n+1) a[i] = lower_bound(v+1,v+1+n,a[i])-(v+1);因此一共需要n位来存储。这样就可以直接对m个查询当成是m*3个query来做了。对于每一个原创 2021-04-21 09:12:27 · 74 阅读 · 0 评论 -
「JOISC 2014 Day1」历史研究
给出一个序列,问[l,r]区间内ai个数w的权值ai*w的最大值。还是求各种区间的统计值,继续莫队。由于这里是求区间里面的单点最大值,因此不能用普通的莫队。对区间sqrt(n)分块后,一个一个区间处理。按l的区间排序。如果同区间,则按r排序。在处理同一个l区间时,由于r是有序的,r不断的往前移动o(n)。对于l,l的活动范围就是sqrt(n)。l每次都从区间的右边开始往左边移动,然后不断的统计。对于r在区间内的,这种需要特殊处理。由于r在区间内的只有sqrt(n...原创 2021-04-21 04:43:54 · 208 阅读 · 0 评论 -
#58. 【WC2013】糖果公园
给出一棵n个节点的树,每个节点都有一种颜色c[i]。q次询问[l,r]路径上的点的权值和vjwi。每一个节点的权值就是当前节点的颜色值v[c[i]]和从l到该节点经过该颜色的次数num[c[i]]对应的w值w[num[c[i]]之间的乘积(很绕,看题目描述吧,懒得描述了)这是树上莫队。分块是对子树进行。如果一个某一个子树的size满足块大小,则分成一块。void dfs1(int t, int f){ sz[t]=1; fa[t] = f; dp[t] = dp[f]+1;...原创 2021-04-20 20:08:54 · 132 阅读 · 0 评论 -
P1903 [国家集训队]数颜色 / 维护队列
给出一个大小为n的数组,有q次操作(查询[l,r]区间有多少个不同数或者修改某一个值)。带修改的莫队。和普通莫队不同的是多了一维时间。因此在做区间修改之间,需要把时间序列修补一下。保存查询的时候需要保存当前修改序列的时间,在查询的时候需要走到当前时间。另外在排序的时候,第二关键字r不再是奇偶block去排了,如果block相等,则按查询顺序,不相等则直接按r的大小。block的大小从sqrt(n) 变成n^2/3。int block_size;struct query{ ..原创 2021-04-19 19:39:42 · 78 阅读 · 0 评论 -
P1494 [国家集训队]小Z的袜子
给出m个查询[l,r],问[l,r]区间内随机拿出两双相同袜子的概率。基础莫队题。对查询进行分块排序后,对l,r区间移来移去统计一下。这里卡常数,比较器里面不能有除法。int block_num;struct query{ int l,r,id; int block; bool operator<(const query &q) const{ if(block != q.block) return l<q.l; return ((q.block)&a.原创 2021-04-19 02:29:32 · 68 阅读 · 0 评论