社区讨论
求问
P13981数列分块入门 6参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mlnycvro
- 此快照首次捕获于
- 2026/02/16 00:21 4 天前
- 此快照最后确认于
- 2026/02/16 21:56 3 天前
我的做法大概是对于块长 ,每 个元素用一个链表维护,然后使用一个新的链表维护这 个链表。
查询时,在大链表上顺序遍历,找到需要查询的元素在哪个小链表里,然后暴力进去查找即可。
修改时,找到对应的小链表,然后直接插进去即可。
不过要注意,当一个小链表长度超过 时,就要拆成两个新的小链表,然后插到大链表中。
然后呢,我按照这个要求写了一份代码,在洛谷上直接过了:
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
bool ST;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline void pc(char ch){putchar(ch);}
inline void write(int x){
if(x < 0) pc('-'), x = -x;
if(x > 9) write(x / 10);
pc(x % 10 + '0');
return;
}
const int B = 548; // 一杯茶,一包烟,一个块长调一天
struct LinkedList{
int len = 0, a[(B << 1) + 5], nxt[(B << 1) + 5], pre[(B << 1) + 5], lst;
inline void clear(){
len = lst = 0;
memset(a, 0, sizeof(a));
memset(nxt, 0, sizeof(nxt));
memset(pre, 0, sizeof(pre)); // memset 吧,反正不是复杂度瓶颈
return;
}
inline int getid(int x){
int p = 0;
while(x--) p = nxt[p];
return p;
}
inline void append(int k){
a[++len] = k;
nxt[lst] = len;
pre[len] = lst;
lst = len;
return;
}
inline void insert(int x, int k){
x = getid(x);
a[++len] = k;
nxt[pre[x]] = len;
pre[len] = pre[x], nxt[len] = x;
pre[x] = len;
return;
}
inline int query(int x){
int u = 0;
while(x--) u = nxt[u];
return a[u];
}
}xlb[(B << 1) + 5], dlb; // 小链表,大链表
int n, a[300005], len;
inline void init(){
int i = 1;
while(i <= n){
len++;
while(xlb[len].len <= B){
xlb[len].append(a[i++]);
}
dlb.append(len);
}
return;
}
inline void modify(int x, int k){
int xid = 1;
while(xlb[xid].len < x) x -= xlb[xid].len, xid++;
xlb[xid].insert(x, k);
if(xlb[xid].len >= (B << 1)){
vector<int> v;
int p = xlb[xid].nxt[0];
while(p) v.push_back(p), p = xlb[xid].nxt[p];
xlb[xid].clear();
for(int i = 0; i < B; i++) xlb[xid].append(v[i]);
len++;
for(int i = B; i < (int)v.size(); i++) xlb[len].append(v[i]);
dlb.insert(dlb.nxt[xid], len);
}
return;
}
inline int query(int x){
int xid = 1;
while(xlb[xid].len < x) x -= xlb[xid].len, xid++;
return xlb[xid].query(x);
}
bool ED;
signed main(){
n = read();
for(int i = 1; i <= n; i++) a[i] = read();
init();
int q = n;
while(q--){
int op = read();
if(op == 0){
int l = read(), r = read();
modify(l, r);
}else{
int x = read();
write(query(x)), pc('\n');
}
}
cerr << 1.0 * abs(&ED - &ST) / 1024 / 1024 << " MB" << '\n';
return 0;
}
然后改了输入格式交到 loj 上,全 WA。
我尝试修改了块长,然后发现 越大,对的行数就越多。
求问原因 qwq
回复
共 1 条回复,欢迎继续交流。
正在加载回复...