考虑分块,每个块都是用 链表 维护的,并保证 \(size\) 和分块相当。

我们考虑一下怎么去查询,很显然,可以对值域分块,单点修改,记录前缀和,完全ojbk了,对每个块维护一个 \(pre , prb\) 数组

\(pre_{i,j}\) 数组表示 \(1~i\) 这些块中,出现了多少个 \(j\)

\(prb_{i,j}\) 数组表示 \(1~i\) 这些块中,在值域块 \(j\) 的有多少个

零散部分查一查就好了,修改也是稳定 \(\sqrt n\) 的,插入也是。

// powered by c++11
// by Isaunoya
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
using namespace std;
using db = double;
using ll = long long;
using uint = unsigned int;
using pii = pair<int, int>;
#define ve vector
#define Tp template
#define all(v) v.begin(), v.end()
#define sz(v) ((int)v.size())
#define pb emplace_back
#define fir first
#define sec second
// the cmin && cmax
Tp<class T> void cmax(T& x, const T& y) {
if (x < y) x = y;
}
Tp<class T> void cmin(T& x, const T& y) {
if (x > y) x = y;
}
// sort , unique , reverse
Tp<class T> void sort(ve<T>& v) { sort(all(v)); }
Tp<class T> void unique(ve<T>& v) {
sort(all(v));
v.erase(unique(all(v)), v.end());
}
Tp<class T> void reverse(ve<T>& v) { reverse(all(v)); }
const int SZ = 0x191981;
struct FILEIN {
char qwq[SZ], *S = qwq, *T = qwq, ch;
char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
FILEIN& operator>>(char& c) {
while (isspace(c = GETC()))
;
return *this;
}
FILEIN& operator>>(string& s) {
while (isspace(ch = GETC()))
;
s = ch;
while (!isspace(ch = GETC())) s += ch;
return *this;
}
Tp<class T> void read(T& x) {
bool sign = 1;
while ((ch = GETC()) < 0x30)
if (ch == 0x2d) sign = 0;
x = (ch ^ 0x30);
while ((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30);
x = sign ? x : -x;
}
FILEIN& operator>>(int& x) { return read(x), *this; }
FILEIN& operator>>(unsigned& x) { return read(x), *this; }
} in;
struct FILEOUT {
const static int LIMIT = 0x114514;
char quq[SZ], ST[0x114];
signed sz, O;
~FILEOUT() { flush(); }
void flush() {
fwrite(quq, 1, O, stdout);
fflush(stdout);
O = 0;
}
FILEOUT& operator<<(char c) { return quq[O++] = c, *this; }
FILEOUT& operator<<(string str) {
if (O > LIMIT) flush();
for (char c : str) quq[O++] = c;
return *this;
}
Tp<class T> void write(T x) {
if (O > LIMIT) flush();
if (x < 0) {
quq[O++] = 0x2d;
x = -x;
}
do {
ST[++sz] = x % 0xa ^ 0x30;
x /= 0xa;
} while (x);
while (sz) quq[O++] = ST[sz--];
return;
}
FILEOUT& operator<<(int x) { return write(x), *this; }
FILEOUT& operator<<(unsigned x) { return write(x), *this; }
} out;
int n, m;
const int maxn = 7e4 + 47;
const int blc = 235;
const int S = 300;
list<int> s[S];
#define bl(x) ((x - 1) / S + 1)
int pre[maxn][S], prb[S][S], L[S], R[S], cnt[maxn], t[S], st[S << 1], top = 0, ans = 0;
inline int modify(list<int>& l, int x, int v) {
auto it = l.begin();
while (x--) ++it;
int res = *(it);
return *(it) = v, res;
}
inline void get(list<int>& l, int x, int y) {
auto it = l.begin();
while (x--) ++it;
while (y--) {
++cnt[st[++top] = *(it)], ++t[bl(*(it))], ++it;
}
}
void qry(int l, int r, int k) {
top = 0;
const int bL = bl(l), bR = bl(r);
if (bL == bR) {
get(s[bL], l - L[bL], r - l + 1);
for (int i = 1;; i++) {
if (k > t[i]) {
k -= t[i];
} else {
for (int j = L[i];; ++j)
if (k > cnt[j]) {
k -= cnt[j];
} else {
ans = j;
break;
}
break;
}
}
} else {
get(s[bL], l - L[bL], R[bL] - l + 1), get(s[bR], 0, r - L[bR] + 1);
for (int i = 1;; i++) {
if (k > t[i] + prb[i][bR - 1] - prb[i][bL]) {
k -= (t[i] + prb[i][bR - 1] - prb[i][bL]);
} else {
for (int j = L[i];; ++j)
if (k > cnt[j] + pre[j][bR - 1] - pre[j][bL]) {
k -= (cnt[j] + pre[j][bR - 1] - pre[j][bL]);
} else {
ans = j;
break;
}
break;
}
}
}
ans--;
for (int i = 0; i <= top; i++) {
t[bl(st[i])] = 0, cnt[st[i]] = 0;
}
}
inline void change(int x, int v) {
const int bel = bl(x);
int las = modify(s[bel], x - L[bel], v);
for (int i = bel; i <= blc; i++) {
--pre[las][i], --prb[bl(las)][i], ++pre[v][i], ++prb[bl(v)][i];
}
}
inline void ins(int x, int v) {
const int bel = bl(x);
auto it = s[bel].begin();
for (int i = x - L[bel]; i--;) ++it;
s[bel].insert(it, v);
for (int i = bel; i <= blc; i++) {
++pre[v][i], ++prb[bl(v)][i];
}
for (int i = bel + 1; i <= blc; i++) {
if (s[i - 1].size() <= S) {
break;
} else {
int las = s[i - 1].back();
--pre[las][i - 1], --prb[bl(las)][i - 1];
s[i - 1].pop_back(), s[i].push_front(las);
}
}
}
signed main() {
#ifdef _WIN64
freopen("testdata.in", "r", stdin);
#else
ios_base ::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
#endif
// code begin.
in >> n;
rep(i, 1, blc) { L[i] = R[i - 1] + 1, R[i] = L[i] + S - 1; }
rep(i, 1, n) {
int x;
const int bel = bl(i);
in >> x, ++x, s[bel].pb(x);
rep(j, bel, blc) { ++pre[x][j], ++prb[bl(x)][j]; }
}
in >> m;
while (m--) {
char c;
in >> c;
if (c == 'Q') {
int l, r, k;
in >> l >> r >> k, qry(l ^ ans, r ^ ans, k ^ ans), out << ans << '\n';
}
if (c == 'M') {
int x, v;
in >> x >> v, x ^= ans, v ^= ans, ++v, change(x, v);
}
if (c == 'I') {
int x, v;
in >> x >> v, x ^= ans, v ^= ans, ++v, ins(x, v);
}
}
return 0;
// code end.
}

「BZOJ3065」带插入区间K小值 [分块]的更多相关文章

  1. 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树

    [BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...

  2. 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树

    题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...

  3. 【BZOJ3065】带插入区间k小值

    题意: 带插入,修改的区间k小值在线查询 原序列长度<=35000,插入个数<=35000,修改个数<=70000,0<=权值<=70000 题解: Orz vfleak ...

  4. 【bzoj3065】: 带插入区间K小值 详解——替罪羊套函数式线段树

    不得不说,做过最爽的树套树———— 由于有了区间操作,我们很容易把区间看成一棵平衡树,对他进行插入,那么外面一层就是平衡树了,这就与我们之前所见到的不同了.我们之前所见到的大多数是线段树套平衡树而此题 ...

  5. BZOJ3065:带插入区间K小值

    浅谈树状数组与主席树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...

  6. [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树

    刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...

  7. bzoj 3065: 带插入区间K小值 替罪羊树 && AC300

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Des ...

  8. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  9. 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树

    经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...

随机推荐

  1. 1240: 函数strcmp的设计

    #include <string.h>#include <stdio.h>int mycmp(char*s1,char*s2);int main(){ int sum; cha ...

  2. 搭建DevOps模式的项目

    在后端的开发领域,各类开发框架都已经很多,在开发项目时可以根据不同的需要和需求选择合适的开发框架.然而在需要开发一个完善的工程化项目时,仅仅一个后端开发框架是不够的,还面临着在对开发项目的快速迭代中进 ...

  3. java代码之美(14)---Java8 函数式接口

    Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加 ...

  4. 重磅!K8S 1.18版本将内置支持SideCar容器。

    作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...

  5. C++类中拷贝构造函数详解

    a. C++标准中提到"The default constructor, copy constructor and copy assignment operator, and destruc ...

  6. react项目中引用amap(高德地图)坑

    最近在写一个react项目,用到了需要定位的需求,于是乎自己决定用高德地图(AMap),但是react官方文档的案列很少,大多都是原生JS的方法. 在调用amap的 Geocoder Api 时,一直 ...

  7. SpringProfile轻松切换多环境配置文件

    在项目开发的过程中,我们难免会遇到开发.测试.生产等环境的切换,而各个环境的配置肯定是不同的.传统的办法是在项目打包的时候修改配置文件.但人为做的事情难免产生意外.Spring 为我们提供了一种多环境 ...

  8. CentOS7.x以上版本配置DNS失效解决办法

    这2周做实验,centos7.x经常出现yum安装软件包的时候找不到解析地址,提示如下错误 正在尝试其它镜像. Error downloading packages: pam-devel-1.1.8- ...

  9. VMware克隆Linux虚拟机报错

    在VMware里克隆了2个centos6.5,执行命令重启网卡服务报以下错误: Bringing up interface eth0: Device eth0 does not seem to be ...

  10. iTerm 2 与 oh-my-zsh配合,自定义你的终端。

    参考博客:https://www.cnblogs.com/xishuai/p/mac-iterm2.html 参考博客:https://www.cnblogs.com/sasuke6/p/497607 ...