codeforces 455D 分块
2017-08-30 23:25
204 查看
简略题意:初始给出长度为n的数组a[i],
有两种操作,共q次。
1.将a[l],a[l+1],...,a[r]中的a[r]移动到a[l]处,之后的元素后移一位.
2.问区间[l,r]有多少数等于k.
要求强制在线。
看起来就是个数据结构,然而我们很难找到一个成熟的模型来套。
那么考虑分块,对于操作1, 若[l,r]在同一块,直接暴力处理,O(n√),否则我们只需要维护n√ 个双端队列,对于l所在的块,r所在的块暴力处理,中间每一块O(1)处理,复杂度O(n√).
对于操作2同理,O(n√)。
总复杂度O(q∗n√)。
写起来还是需要注意细节的。
有两种操作,共q次。
1.将a[l],a[l+1],...,a[r]中的a[r]移动到a[l]处,之后的元素后移一位.
2.问区间[l,r]有多少数等于k.
要求强制在线。
看起来就是个数据结构,然而我们很难找到一个成熟的模型来套。
那么考虑分块,对于操作1, 若[l,r]在同一块,直接暴力处理,O(n√),否则我们只需要维护n√ 个双端队列,对于l所在的块,r所在的块暴力处理,中间每一块O(1)处理,复杂度O(n√).
对于操作2同理,O(n√)。
总复杂度O(q∗n√)。
写起来还是需要注意细节的。
#include <bits/stdc++.h> #define all(x) x.begin(), x.end() using namespace std; typedef long long LL; const int maxn = 100002; int block, num, belong[maxn]; int mp[400][100001]; pair<int, int> mark[maxn]; deque<int> V[400]; int n; void build() { block = sqrt(n); num = n / block; if(n % block) num++; for(int i = 1; i <= n; i++) belong[i] = (i-1)/block+1; } void update(int l, int r) { pair<int, int> pos1 = mark[l], pos2 = mark[r]; int f1 = pos1.first, s1 = pos1.second; int f2 = pos2.first, s2 = pos2.second; int valr = V[f2][s2]; deque<int> &dq = V[f1]; if(f1 == f2) { dq.insert(dq.begin() + s1, valr); dq.erase(dq.begin() + s2 + 1); return ; } mp[f1][valr]++; V[f1].insert(dq.begin() + s1, valr); int vv = *V[f1].rbegin(); V[f1].pop_back(); mp[f1][vv]--; for(int i = f1 + 1; i < f2; i++) { V[i].push_front(vv); mp[i][vv]++; vv = *V[i].rbegin(); mp[i][vv]--; V[i].pop_back(); } mp[f2][valr]--; V[f2].erase(V[f2].begin() + s2); mp[f2][vv]++; V[f2].push_front(vv); } LL lans = 0; int decode(int x) { return (x + lans - 1)%n+1; } int ask(int l, int r, int k) { pair<int, int> pos1 = mark[l], pos2 = mark[r]; int f1 = pos1.first, s1 = pos1.second; int f2 = pos2.first, s2 = pos2.second; int cnt = 0; if(f1 == f2) { for(int i = s1; i <= s2; i++) if(V[f1][i] == k) cnt++; } else { for(int i = s1; i < V[f1].size(); i++) if(V[f1][i] == k) cnt++; for(int i = 0; i <= s2; i++) if(V[f2][i] == k) cnt++; for(int i = f1 + 1; i < f2; i++) cnt+=mp[i][k]; } return cnt; } void show() { for(int i = 1; i <= num; i++) for(int j =0; j < V[i].size(); j++) cout<<V[i][j]<<" "; puts(""); } int main() { scanf("%d", &n); build(); for(int i = 1; i <= n; i++) { int v; scanf("%d", &v); V[belong[i]].push_back(v); mark[i] = {belong[i], V[belong[i]].size()-1}; mp[belong[i]][v]++; } int q; scanf("%d", &q); for(int i = 1; i <= q; i++) { int c, u, v; scanf("%d%d%d", &c, &u, &v); u = decode(u), v = decode(v); if(u > v) swap(u, v); if(c == 1) { update(u, v); } else { int k; scanf("%d", &k); k = decode(k); lans = ask(u, v, k); printf("%d\n", lans); } } return 0; }
相关文章推荐
- [Codeforces 455D] Serega and Fun (分块)
- 【分块】 codeforces 455D - Serega and Fun
- Codeforces 551E - GukiZ and GukiZiana(分块)
- codeforces 551E GukiZ and GukiZiana 分块
- codeforces 86D. Powerful array(分块)
- Codeforces 785E Anton and Permutation(分块)
- CodeForces 13E Holes(分块处理)
- [除法分块] Codeforces 830C Bamboo Partition
- Codeforces 551E GukiZ and GukiZiana (分块)
- CodeForces 785E Anton and Permutation 分块
- 【CodeForces】80D Time to Raid Cowavans 分块
- CodeForces 13E. Holes 分块处理
- Codeforces 785E 分块+树状数组
- Codeforces 474F(分块)
- CodeForces 348 C.Subset Sums(分块)
- Codeforces 307 div2 E.GukiZ and GukiZiana 分块
- Codeforces 122 C. Lucky Sum(分块)
- CodeForces 551E GukiZ and GukiZiana 【分块】
- 【codeforces 731F】【前缀和 分块求和 好题】F. Video Cards
- codeforces 551E GukiZ and GukiZiana 分块