1 条题解

  • 0
    @ 2025-10-26 17:41:27
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 500000;
    int n, c, d, p[maxn + 10];
    bool vis[maxn + 10];
    ll a, b, s = 1;
    int main() {
        scanf("%d%lld%lld%d%d", &n, &a, &b, &c, &d);
    
        for (int i = 1; i <= n; ++i)
            scanf("%d", &p[i]);
    
        for (int i = 1; i <= n; ++i)
            if (!vis[i]) {
                int cnt = 0;
                bool is = 0;
    
                for (int j = i; !vis[j]; j = p[j]) {
                    vis[j] = 1;
                    ++cnt;
    
                    if (j > c && j <= n - d) {
                        is = 1;
                    }
                }
    
                if (is) {
                    s = s / __gcd<ll>(s, cnt) * cnt;
    
                    if (s > b) {
                        printf("%d", a == 1 ? 1 : 0);
                        return 0;
                    }
                }
            }
    
        printf("%lld", (b + s - 1) / s - (a + s - 2) / s);
    }
    

    算法标签

    置换循环置换循环周期分析周期分析最小公倍数(LCM最小公倍数(LCM)数论数论

    简要题解

    核心问题是分析纸带每行的周期性,找出与新纸带首行相同的行数。

    1. 置换与周期:机器的打乱操作是一个排列ss,每行的生成是对前一行的列进行置换。因此,每行状态的变化具有周期性,周期由置换的循环结构决定。
    2. 关键列筛选:新纸带保留的列是CC+11nn-DD(即jj > CCjjnn-DD)。只有包含这些列的置换循环,其周期才会影响新纸带的行状态。
    3. 周期计算:对所有包含关键列的循环,求其长度的最小公倍数(LCMLCM),记为ss,这是新纸带行状态重复的周期。
    4. 统计符合条件的行:在[A,B][A, B]范围内,统计是ss的倍数的行数(首行对应11,计数时适配此特殊情况)。

    最终答案为[A,B][A, B]ss的倍数的个数。

    • 1

    信息

    ID
    4196
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者