zoukankan      html  css  js  c++  java
  • [CF455D] Serega and Fun

    [CF455D] Serega and Fun - 分块

    Description

    给定长度为N(N<=100000)的序列,支持两种操作:1 l r 将区间l到r依次向右移动一位,a[r]移动到 [l],2 l r k 询问区间l到r中k出现次数。

    Solution

    考虑分块,每个块内用 deque 维护(这个东西好处就在于不仅支持双端操作还可以下标索引),同时维护一个块内每个值的出现次数

    然后对于操作就暴力处理一下

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int B = 360;
    const int N = 100005;
    
    int block(int x)
    {
        return x / B;
    }
    
    int offset(int x)
    {
        return x % B;
    }
    
    deque<int> a[B];
    signed c[B][N];
    
    int n, q;
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for (int i = 0; i < n; i++)
        {
            int x;
            cin >> x;
            a[block(i)].push_back(x);
            c[block(i)][x]++;
        }
        cin >> q;
        int lastans = 0;
        for (int i = 0; i < q; i++)
        {
            int op, l, r, k;
            cin >> op >> l >> r;
            l = (l + lastans - 1) % n;
            r = (r + lastans - 1) % n;
    
            if (l > r)
                swap(l, r);
            if (op == 2)
                cin >> k;
            k = (k + lastans - 1) % n + 1;
    
            int L = block(l);
            int R = block(r);
            l = offset(l);
            r = offset(r);
    
            if (op == 1)
            {
                if (L == R)
                {
                    int x = a[R][r];
                    a[R].erase(a[R].begin() + r);
                    a[L].insert(a[L].begin() + l, x);
                }
                else
                {
                    for (int i = L; i < R; i++)
                    {
                        int x = a[i].back();
                        a[i].pop_back();
                        c[i][x]--;
                        c[i + 1][x]++;
                        a[i + 1].push_front(x);
                    }
                    int x = a[R][r + 1];
                    a[R].erase(a[R].begin() + r + 1);
                    a[L].insert(a[L].begin() + l, x);
                    c[R][x]--;
                    c[L][x]++;
                }
            }
            else
            {
                int ans = 0;
                if (L == R)
                {
                    for (int i = l; i <= r; i++)
                        ans += a[L][i] == k;
                }
                else
                {
                    for (int i = l; i < a[L].size(); i++)
                        ans += a[L][i] == k;
                    for (int i = 0; i <= r; i++)
                        ans += a[R][i] == k;
                    for (int i = L + 1; i <= R - 1; i++)
                        ans += c[i][k];
                }
                cout << (lastans = ans) << endl;
            }
        }
    }
    
  • 相关阅读:
    逆袭之旅DAY31.XIA.JDBC
    逆袭之旅DAY30.XIA.集合
    亮晶晶幼儿园家校沟通平台的设计与实现
    逆袭之旅DAY28.XIA.异常处理
    LY.JAVA.DAY12.String类
    2018年7月23日-星期二
    LY.JAVA.DAY12.Scanner
    DAY27.XIA.面向對象
    职业生涯规划
    如何找到自己喜欢的职业
  • 原文地址:https://www.cnblogs.com/mollnn/p/14659160.html
Copyright © 2011-2022 走看看