因此任务是这样的:给您一个大小为n的数组Arr。数组的元素范围是1到n。您有两种查询类型:
链接到原始问题:https://codeforces.com/contest/455/problem/D
我决定这样做: 让我们将Arr数组划分为sqrt(n)个块。 让我们存储sqrt(n)双端队列(C ++ STL双端队列)。 还让我们存储sqrt(n)计数器数组,其中cnt [i] [j]是数字j在第i个块中出现的次数
如果我们仅使用pop_back和push_front更新相应块的双端队列并更新计数器数组,则第一个查询可以在O(sqrt(n))时间完成。
第二个查询可以通过只计算相应块i上的总和cnt [i] [k]来完成。
我正在用WA4来实现这个想法,我找不到代码中的错误,所以我开始想也许这个想法是错误的。你觉得呢?
这是我的投稿
int n;
void decode(int &l, int &r, int lastans) {
l = ((l + lastans - 1) % n);
r = ((r + lastans - 1) % n);
if (l > r)
swap(l, r);
}
void decode(int &l, int &r, int &k, int lastans) {
decode(l, r, lastans);
k = ((k + lastans - 1) % n)+1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
int sqt = sqrt(n + .2) + 1;
vector<deque<int> > b(sqt);
vector<vector<int> > cnt(sqt, vector<int> (n+1));
for (int i = 0; i < n; i++) {
int blok = i / sqt;
b[blok].push_back(a[i]);
cnt[blok][a[i]]++;
}
int q;
cin >> q;
int lastans = 0;
while (q--) {
int l, r, k, t;
cin >> t;
if (t == 1) {
cin >> l >> r;
decode(l, r, lastans);
int b1, b2;
b1 = l / sqt;
b2 = r / sqt;
if (b1 == b2) {
int temp = b[b2][r%sqt];
for (int g = r % sqt; g > l%sqt; g--) {
b[b2][g] = b[b2][g - 1];
}
b[b1][l%sqt] = temp;
}
else {
int temp = b[b2][r%sqt];
cnt[b2][temp]--;
for (int g = r % sqt; g > 0; g--) {
b[b2][g] = b[b2][g - 1];
}
cnt[b2][b[b2].front()]--;
b[b2][0] = b[b2 - 1].back();
cnt[b2][b[b2].front()]++;
for (int g = b2 - 1; g > b1; g--) {
cnt[g][b[g].back()]--;
b[g].pop_back();
b[g].push_front(b[g - 1].back());
cnt[g][b[g].front()]++;
}
cnt[b1][b[b1].back()]--;
for (int g = (int)b[b1].size()-1; g > l%sqt; g--) {
b[b1][g] = b[b1][g - 1];
}
b[b1][l%sqt] = temp;
cnt[b1][temp]++;
}
}
else {
cin >> l >> r >> k;
decode(l, r, k, lastans);
int b1 = l / sqt;
int b2 = r / sqt;
if (b1 == b2) {
int ans = 0;
for (int g = l % sqt; g <= r % sqt; g++) {
ans += b[b1][g] == k ? 1 : 0;
}
lastans = ans;
cout << lastans << '\n';
}
else {
int ans = 0;
for (int g = l % sqt; g < b[b1].size(); g++) {
ans += b[b1][g] == k ? 1 : 0;
}
for (int g = b1 + 1; g < b2; g++) {
ans += cnt[g][k];
}
for (int g = 0; g <= r % sqt; g++)
ans += b[b2][g] == k ? 1 : 0;
lastans = ans;
cout << lastans << '\n';
}
}
}
}