可以使用Deque + Sqrt分解解决Codeforce问题455D吗?

时间:2019-04-17 19:26:48

标签: c++

因此任务是这样的:给您一个大小为n的数组Arr。数组的元素范围是1到n。您有两种查询类型:

  1. (l,r)-在子数组Arr [l,r]的两端进行循环移位。
  2. (l,r,k)-打印出[l,r]范围内等于k的元素数量;

链接到原始问题: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';
            }
        }
    }
}

0 个答案:

没有答案