未来日记
题解
干脆叫它君主贞卡常二世吧,这还得带一个君主buff
首先看到 题目名 出题人,我们可以先猜测它是一个分块,考虑怎么分块。
如果你刚好做过 ZQC 的手办 应该很容易想到题解中给出的一种分块做法。
没错,对于每个块,我们记录它前缀中为 x x x的数的个数以及前缀中在 b l o c k x block_{x} blockx中数的个数,查询就直接像线段树一样,枚举找到它第 k k k小的值。
先找第 k k k小的值所属于的块,再找这个块中对应的值。
记录的是前缀方便我们通过差分找到连续的块中的值。
但修改操作我们该怎么做呢?
对于散块我们就暴力修改,对于整块我们就打上懒标记,然后在块对应的前缀中修改。
但很明显的一点,我们打了懒标记就以为着我们在修改和查询散块时需要将该块懒标记下传后再操作。
我们可以用指针加启发式合并的方式维护懒标记的下传,这就意味着我们对于单块的懒标记下传时间复杂度达到了 O ( S l o g S ) O\left(Slog\,S\right) O(SlogS)。
我们记数域为 M M M,总时间复杂度 O ( n ( M + m ) S + n l o g S + m ( M S ′ + S ′ + S ) ) ⩾ O ( m m + n m ( M + m ) ) O\left(\frac{n(M+m)}{S}+nlog\,S+m(\frac{M}{S'}+S'+S)\right)\geqslant O\left(m\sqrt{m}+\sqrt{nm(M+m)}\right) O(Sn(M+m)+nlogS+m(S′M+S′+S))⩾O(mm+nm(M+m))。
一个很明显可以过的复杂度 ,但这**lxl竟然卡我常!!!真是不可饶恕。
源码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 100005
#define lowbit(x) (x&-x)
#define