链接
题目描述
思路
分块维护不同个数的值,每一块用双端队列去维护轮转
是KouA了啊,因为不是很会实现
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
int A[335][100005], B[100005], C[355], D[355], num, cnt, n, m;
int read()
{
int x = 0, flag = 1; char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') flag = -1; ch = getchar();}
while (ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0'; ch = getchar();}
return x * flag;
}
deque <int>Q[100005];
int main()
{
n = read(); m = read();
num = sqrt(n);
for(int i = 1; i <= n; ++i)
{
int x; x = read();
if(i > num * cnt) ++cnt;
Q[cnt].push_back(x);
B[i] = cnt, ++A[cnt][x];
}
while(m--)
{
int opt; opt = read();
if(opt == 1)
{
int l, r; l = read(); r = read();
if(B[l] == B[r])
{
int G = B[l];
l = l % num; if(l == 0) l = num;
r = r % num; if(r == 0) r = num;
for(int i = 1; i < l; ++i)
C[i] = Q[G].front(), Q[G].pop_front();
for(int i = 1; i <= num - r; ++i)
D[i] = Q[G].back(), Q[G].pop_back();
int x = Q[G].back(); Q[G].pop_back(); Q[G].push_front(x);
for(int i = l - 1; i >= 1; --i) Q[G].push_front(C[i]);
for(int i = 1; i <= num - r; ++i) Q[G].push_back(D[(num - r) - i + 1]);
}
else
{
int G = B[l], k = l; while(B[k + 1] == G) k++;
int len1 = k - l + 1;
for(int i = 1; i <= len1; ++i)
C[len1 - i + 1] = Q[G].back(), Q[G].pop_back(), A[G][C[len1 - i + 1]]--;
int F = B[r], h = r; while(B[h - 1] == F) h--;
int len2 = r - h + 1;
for(int i = 1; i <= len2; ++i)
D[i] = Q[F].front(), Q[F].pop_front(), A[F][D[i]]--;
Q[G].push_back(D[len2]), A[G][D[len2]]++;
for(int i = 1; i < len1; ++i) Q[G].push_back(C[i]), A[G][C[i]]++;
for(int i = len2 - 1; i >= 1; --i) Q[F].push_front(D[i]), A[F][D[i]]++;
int x = Q[F - 1].back(); if(F == G + 1) x = C[len1];
Q[F].push_front(x), A[F][x]++;
int last = C[len1];
for(int i = G + 1; i <= F - 1; ++i)
{
Q[i].push_front(last); A[i][last]++;
last = Q[i].back(); Q[i].pop_back();
A[i][last]--;
}
}
}
else
{
int l, r, K, ans = 0; l = read(); r = read(); K = read();
if(B[l] == B[r])
{
int G = B[l];
l = l % num; if(l == 0) l = num;
r = r % num; if(r == 0) r = num;
for(int i = 1; i < l; ++i)
C[i] = Q[G].front(), Q[G].pop_front();
for(int i = 1; i <= num - r; ++i)
D[i] = Q[G].back(), Q[G].pop_back();
for(int i = l - 1; i >= 1; --i)
{
if(C[i] == K) ans++;
Q[G].push_front(C[i]);
}
for(int i = 1; i <= num - r; ++i)
{
if(D[(num - r) - i + 1] == K) ans++;
Q[G].push_back(D[(num - r) - i + 1]);
}
ans = A[G][K] - ans;
}
else
{
int G = B[l], k = l;
while(B[k + 1] == G) ++k;
int len1 = k - l + 1;
for(int i = 1; i <= len1; ++i)
C[len1 - i + 1] = Q[G].back(), Q[G].pop_back();
for(int i = 1; i <= len1; ++i)
{
if(C[i] == K) ans++;
Q[G].push_back(C[i]);
}
int F = B[r], h = r;
while(B[h - 1] == F) h--;
int len2 = r - h + 1;
for(int i = 1; i <= len2; ++i)
D[i] = Q[F].front(), Q[F].pop_front();
for(int i = len2; i >= 1; --i)
{
if(D[i] == K) ans++;
Q[F].push_front(D[i]);
}
for(int i = G + 1; i <= F - 1; ++i) ans += A[i][K];
}
printf("%d\n", ans);
}
}
return 0;
}