「2016山东省队集训」 Play with array
来源:互联网 发布:淘宝开店店铺简介 编辑:程序博客网 时间:2024/06/05 20:30
Description
Input
Output
Sample Input
7
6 6 2 7 4 2 5
7
1 3 6
2 2 4 2
2 4 6 2
2 3 3 6
1 2 6
1 1 4
2 1 7 3
Sample Output
2
1
0
0
HINT
Source
by faebdc
Solution
块状链表。
- 修改操作可以转化为:删除r、在l前面插入一个数。
- 询问操作可以转化为:区间[1,r]中k出现次数-区间[1,l-1]中k出现次数
对于每个块记录一下每个数字出现了多少次。
错误调试:split的操作要对每个块数字出现次数进行修改。
Code
#include <cstdio>#include <algorithm>using namespace std;const int size = 316;const int maxn = 100005;int getint() { int r = 0, k = 1; char c = getchar(); for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1; for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c; return r * k;}int n, m, totBlock;int data[640][2005], cnt[640][100005], nxtBlock[640], preBlock[640], siz[640], a[maxn];void Build() { totBlock = (n + size - 1) / size; for (int i = 1; i <= totBlock; ++i) { int l = (i - 1) * size + 1, r = min(i * size, n); siz[i] = r - l + 1; for (int j = l; j <= r; ++j) { ++cnt[i][a[j]]; data[i][j - l + 1] = a[j]; } nxtBlock[i] = i + 1; preBlock[i] = i - 1; } nxtBlock[totBlock] = 0;}int Query(int pos) { int tmp = 0; for (int i = 1; i; i = nxtBlock[i]) { tmp += siz[i]; if (pos <= tmp) return data[i][pos - tmp + siz[i]]; }}void Merge(int x, int y) { for (int i = 1; i <= siz[y]; ++i) { data[x][++siz[x]] = data[y][i]; ++cnt[x][data[y][i]]; } nxtBlock[x] = nxtBlock[y];}void Split(int x) { ++totBlock; int half = siz[x] / 2; for (int i = half + 1; i <= siz[x]; ++i) { data[totBlock][++siz[totBlock]] = data[x][i]; --cnt[x][data[x][i]]; ++cnt[totBlock][data[x][i]]; } siz[x] = half; preBlock[totBlock] = x; nxtBlock[totBlock] = nxtBlock[x]; if (nxtBlock[x]) preBlock[nxtBlock[x]] = totBlock; nxtBlock[x] = totBlock;}void Delete(int pos) { int tmp = 0; for (int i = 1; i; i = nxtBlock[i]) { tmp += siz[i]; if (pos <= tmp) { tmp -= siz[i]; --cnt[i][data[i][pos - tmp]]; for (int j = pos - tmp; j <= siz[i]; ++j) data[i][j] = data[i][j + 1]; --siz[i]; if (siz[i] * 2 < size) { if (nxtBlock[i]) { Merge(i, nxtBlock[i]); } else if (preBlock[i]) { Merge(preBlock[i], i); i = preBlock[i]; } } if (siz[i] > size * 2) Split(i); return; } }}void Insert(int pos, int val) { int tmp = 0; for (int i = 1; i; i = nxtBlock[i]) { tmp += siz[i]; if (pos <= tmp) { tmp -= siz[i]; ++cnt[i][val]; for (int j = siz[i]; j >= pos - tmp; --j) data[i][j + 1] = data[i][j]; ++siz[i]; data[i][pos - tmp] = val; if (siz[i] > size * 2) Split(i); return; } }}int Query(int pos, int k) { int tmp = 0, ret = 0; for (int i = 1; i; i = nxtBlock[i]) { tmp += siz[i]; if (pos <= tmp) { pos -= tmp - siz[i]; for (int j = 1; j <= pos; ++j) ret += (data[i][j] == k); return ret; } ret += cnt[i][k]; } return ret;}int main() { freopen("array.in", "r", stdin); freopen("array.out", "w", stdout); int x, l, r, k; n = getint(); for (int i = 1; i <= n; ++i) a[i] = getint(); Build(); m = getint(); for (int i = 1; i <= m; ++i) { x = getint(); l = getint(); r = getint(); if (x == 1) { int tmp = Query(r); Delete(r); Insert(l, tmp); } else { k = getint(); printf("%d\n", Query(r, k) - Query(l - 1, k)); } } fclose(stdin); fclose(stdout); return 0;}
0 0
- 「2016山东省队集训」 Play with array
- 「2016山东省队集训」 LYK loves jumping
- 「2016山东省队集训」 分子切割 molecule
- [SD2016集训]Play with array(分块+双向链表)
- 「2016山东省队集训」 线段树学习之标记永久化
- Test Problem:Play With Array:分块+链表
- 暑期集训之Array
- 「2016湖南集训」 猜测 guess
- Sound play with stream
- Play with Bindings
- Play with libvirt
- play with the winner
- Play with GNU Screen
- hdu3487 Play with Chain
- play with framework
- uva10129(play with words)
- HackerRank: Play with words
- play with 打印机
- 机器人自主移动的秘密:实际应用中,SLAM究竟是如何实现的?(二)SLAM与路径规划有什么关系?(三)
- 布局
- Linux中的粘滞位
- Java设计模式三
- Telnet与SSH两大协议的区别
- 「2016山东省队集训」 Play with array
- 程序设计实训报告 项目2.2
- 算法导论 第八章 线性时间排序
- 使用eclipse远程hive时出现的错误大汇总
- 孙宇教授解读:美国国家机器人计划2.0——无处不在的协作机器人
- shell 脚本各种执行方式(source ./*.sh, . ./*.sh, ./*.sh)的区别
- MATLAB读取不同行列的txt格式文件
- 程序设计实训报告 项目3.2
- 「2016山东省队集训」 分子切割 molecule