数列分块入门 6
思路1:直接用vector操作,简单方便,直接水过
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <stdio.h> #include <algorithm> #include <map> #include <queue> #include <set> #include <sstream> #include <vector> #include <cmath> #include <stack> #include <random> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define LD long double #define LL long long #define PI acos(-1.0) #define INF 0x3f3f3f3f #define inf 1<<30 #define ull unsigned long long const int Mod = 998244353; const int maxn = 1e6 + 5; int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int n,k,opt,l,r,c; vector<int>vt; int main() { io; n = read(); for (int i = 1; i <= n; i++) { k = read(); vt.push_back(k); } for(int i=1;i<=n;i++){ opt=read();l=read();r=read();c=read(); if(opt==0) vt.insert(vt.begin()+l-1,r); else cout<<vt[r-1]<<endl; } return 0; }
思路2:分块,每一块插入到了一定大小后,对所有块进行重构
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <stdio.h> #include <algorithm> #include <map> #include <queue> #include <set> #include <sstream> #include <vector> #include <cmath> #include <stack> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define LD long double #define LL long long #define PI acos(-1.0) #define INF 0x3f3f3f3f #define inf 1<<30 #define ull unsigned long long const int Mod = 998244353; const int maxn = 1e6 + 5; int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int n, opt, l, r, c, k, block, m; int a[maxn]; int v[maxn];//不可以用vector,否则会迷之错误 vector<int>vt[1005]; vector<int>::iterator it; pair<int, int>find(int b) {//返回第b个在第几块的第几个 int x = 1; while (b > vt[x].size()) b -= vt[x].size(), x++; return make_pair(x, b - 1);//记得减一 } void rebuild() {//重构 int tot = 0; for (int i = 1; i <= m; i++) {//遍历所有块的所有数 for (it = vt[i].begin(); it != vt[i].end(); it++) { v[++tot] = *it; } vt[i].clear();//清空块 } int block2 = sqrt(tot); m = (tot - 1) / block2 + 1; for (int i = 1; i <= tot; i++) {//重新分配 k = (i - 1) / block2 + 1; vt[k].push_back(v[i]); } } void add(int step, int val) { pair<int, int>q = find(step);//返回插入位置 vt[q.first].insert(q.second + vt[q.first].begin(), val); if (vt[q.first].size() > 20 * block)//满足条件重构 rebuild(); } int main() { scanf("%d", &n); block = sqrt(n); m = (n - 1) / block + 1; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for (int i = 1; i <= n; i++) { k = (i - 1) / block + 1; vt[k].push_back(a[i]); } for (int i = 1; i <= n; i++) { scanf("%d%d%d%d", &opt, &l, &r, &c); if (opt == 0) { add(l, r); } else { pair<int, int> t = find(r);//返回位置 printf("%d\n", vt[t.first][t.second]); } } }