一开始我用分块大法,分成$\sqrt{n}$块,每个块上维护一个Splay,然后balabala维护一下,时间复杂度是$O(n\sqrt{n}logn)$。后来对拍的时候发现比$O(n^2)$的暴力跑得还慢,xxy学长说是Splay常数太大2333333

考试的时候没想到可以在每个块上建一个$10^5$的数组来存储每个数字出现的次数,而是用了常数巨大且复杂度多了一个log的SplayQwQ,发现自己完全没有对空间复杂度的认识啊(┙>∧<)┙へ┻┻

标算是块状链表,什么balabala比较基础地维护,卡着空间开2333333

我把块的大小设为$[\frac{\sqrt{n}}{2},\sqrt{n}×2)$,在codevs上TLE,,,

后来把块的大小改成了$[\sqrt{n},\sqrt{n}×2)$,1s内能轻松跑过。

也许是因为某些玄学的原因吧,,,

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100000;
const int B = 316;
const int BB = 632; int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} struct BLOCK {
BLOCK() {
nxt = NULL;
len = 0;
memset(times, 0, sizeof(times));
}
BLOCK *nxt;
int a[BB + B + 3], times[N + 1], len;
}; int cnt = 0;
int n; namespace BlockList {
BLOCK *head;
void Build(BLOCK * t) {head = t;}
void split(BLOCK *r) {
int rlen = r->len / 2, tlen = r->len - rlen, to = rlen;
BLOCK *t = new BLOCK;
memcpy(t->a + 1, r->a + rlen + 1, sizeof(int) * tlen);
for(int i = 1; i <= tlen; ++i) {
++t->times[t->a[i]];
--r->times[t->a[i]];
}
t->len = tlen;
r->len = rlen;
t->nxt = r->nxt;
r->nxt = t;
}
void merge(BLOCK *r) {
BLOCK *t = r->nxt;
if (t == NULL) return;
int tlen = t->len, to = r->len;
memcpy(r->a + to + 1, t->a + 1, sizeof(int) * tlen);
for(int i = 1; i <= tlen; ++i)
++r->times[t->a[i]];
r->len += tlen;
t = t->nxt;
delete r->nxt;
r->nxt = t;
if (r->len >= BB) split(r);
}
BLOCK *find(int &k) {
BLOCK *t = head;
while (k - t->len > 0 && t != NULL) {
k -= t->len;
t = t->nxt;
}
return t;
}
void work(int l, int r) {
BLOCK *t = find(r);
int num = t->a[r];
--t->times[num];
int tlen = --t->len;
for(int i = r; i <= tlen; ++i)
t->a[i] = t->a[i + 1];
if (t->len < B) merge(t);
t = find(l);
for(int i = ++t->len; i > l; --i)
t->a[i] = t->a[i - 1];
t->a[l] = num;
++t->times[num];
if (t->len >= BB) split(t);
}
int query(int l, int r, int k) {
BLOCK *tl = find(l), *tr = find(r);
int ret = 0;
if (tl == tr) {
for(int i = l; i <= r; ++i)
if (tl->a[i] == k) ++ret;
return ret;
} else {
int lentl = tl->len;
for(int i = l; i <= lentl; ++i)
if (tl->a[i] == k) ++ret;
for(int i = 1; i <= r; ++i)
if (tr->a[i] == k) ++ret;
for(tl = tl->nxt; tl != tr && tl != NULL; ret += tl->times[k], tl = tl->nxt);
return ret;
}
}
} int main() {
n = in();
int c = 0, k;
BLOCK *tmp = new BLOCK;
BlockList::Build(tmp);
for(int i = 1; i <= n; ++i) {
++c;
if (c > B) {
c = 1;
tmp->len = B;
tmp->nxt = new BLOCK;
tmp = tmp->nxt;
}
k = in();
tmp->a[c] = k;
++tmp->times[k];
}
tmp->len = c;
int m = in(), op, l, r;
while (m--) {
op = in(); l = in(); r = in();
if (op == 1)
BlockList::work(l, r);
else {
k = in();
printf("%d\n", BlockList::query(l, r, k));
}
}
return 0;
}

继续颓文化课,期末考试Bless All!

最新文章

  1. JVM学习(1)——通过实例总结Java虚拟机的运行机制
  2. 一种面向对象的TCP/IP中间件
  3. ZOJ Problem Set - 1338 Up and Down Sequences 解释 ac代码
  4. LruCache缓存
  5. nginx服务器配置
  6. linux chmod 755
  7. 常见sizeof 笔试题
  8. windows下使用VS2010编译jpeglib
  9. 安装SQL Server 2005
  10. iOS开发XCODE5 SVN配置 使用办法
  11. Uncaught TypeError: Object #&lt;Object&gt; has no method &#39;fancybox&#39;
  12. MongDB主从复制、复制集
  13. jenkins+svn+gradle自动化部署笔记
  14. python变量、条件循环语句
  15. RF新手常见问题总结
  16. MyBatis:参数传递 [转]
  17. (转)Awesome Knowledge Distillation
  18. NOIP2018复赛获奖名单
  19. 使用jquery方法的时候,要注意对象是哪个,否则很容易出错
  20. ajax乱码解决汇总

热门文章

  1. Java Web开发之Servlet获取ckeditor内容
  2. poj2486Apple Tree[树形背包!!!]
  3. POJ1276Cash Machine[多重背包可行性]
  4. java之多线程之一/序列化和反序列化
  5. NSIS来自己设定快捷方式的图标
  6. javascript中的链表结构—从链表中删除元素
  7. SPM FDR校正
  8. UOJ #150 【NOIP2015】 运输计划
  9. MongoDB JAVA API Filters
  10. Construct Binary Tree from Inorder and Postorder Traversal