1 solutions

  • 0
    @ 2025-8-17 14:33:30

    题意

    题目每次询问,如果能通过多次操作把一个序列变成全0,则输出yes,每次操作可以往长度为KK的区间加上某个数cccc 可以是负数。

    题解

    往区间加一个数等于往差分序列两个点加数,所以这里可以看成对两个位置A[i]+cA[i] + cA[i+K]cA[i+K] - c。可以发现,对于A[i+x×K]A[i + x \times K],这些数可以分作一组。即 {A[1],A[1+K],A[1+2×K]}\{A[1], A[1 + K], A[1 + 2 \times K] \dots \}这些数之间的操作才会影响到对方,当这组数为00时,才可以通过调整变成区间全为00。 进而对于区间查询 [l,r][l,r] A[l]+A[l+L]A[l+L1]+..=0A[l] + A[l + L] - A[l + L - 1] + .. = 0可以得出 A[l]+A[l+L]+...=A[1+L1]A[l] + A[l + L] + ... = A[1 + L - 1]+A[1+2L1]... + A[1 + 2 * L - 1] ... 所以可以得到当区间内所有数的%L项的和相等时,差分和也为0

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int N, K;
        cin >> N >> K;
        vector<int> a(N);
        for (auto &x : a)
            cin >> x;
        vector<vector<ll>> sum(K + 1, vector<ll>(N + 1));
        for (int k = 0; k < K; k++)
            for (int i = 0; i < N; i++)
            {
                sum[k][i + 1] = sum[k][i] + (i % K == k ? a[i] : 0);
            }
        int Q;
        cin >> Q;
        while (Q--)
        {
            int l, r;
            cin >> l >> r;
            l--;
            bool ok = true;
            for (int k = 0; k < K; k++)
            {
                if (sum[k][r] - sum[k][l] != sum[0][r] - sum[0][l])
                    ok = false;
            }
            if (ok)
            {
                cout << "Yes\n";
            }
            else
                cout << "No\n";
        }
        return 0;
    }
    
    • 1

    Information

    ID
    40
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    5
    Tags
    (None)
    # Submissions
    9
    Accepted
    3
    Uploaded By