KSzsh

导航

Range Add Query

题目链接

题目描述:

You are given an integer sequence of length \(N\), \(A=(A_1 ,A_2 ,…,A_N​)\), and a positive integer \(K\).

For each \(i=1,2,…,Q\), determine whether a contiguous subsequence of \(A, (A_{l_i} ,A _{l_i+1},…,A_{r_i})\), is a good sequence.

Here, a sequence of length \(n\), \(X=(X_1,X_2,…,X_n)\), is good if and only if there is a way to perform the operation below some number of times (possibly zero) to make all elements of \(X\) equal \(0\).

  • Choose an integer \(i\) such that \(1≤i≤n−K+1\) and an integer \(c\) (possibly negative). Add \(c\) to each of the \(K\) elements \(X_i ,X_{i+1} ,…,X_{i+K−1}\).

It is guaranteed that \(r_i −l_i +1≥K\) for every \(i=1,2,…,Q\).

  • \(1≤N≤2×10^5\)
  • \(1≤K≤min\begin{Bmatrix}10, N\end{Bmatrix}\)
  • \(−10^9 ≤A_i ≤10^9\)
  • \(1≤Q≤2×10^5\)
  • \(1≤l_i ,r_i ≤ N\)
  • \(r_i −l_i+1≥K\)
  • All values in the input are integers.

输入描述:

\( N K \)

\( A_1 A_2 ... A_N \)

\( Q \)

\( l_1 r_1\)

\( l_2 r_2 \)

\( ⋮ \)

\( l _Q r_Q \)

输出描述:

Print \(Q\) lines. For each \(i=1,2,…,Q\), the \(i\)-th line should contain Yes if the sequence \((A_{l_i} ,A_{l_{i+1}} ,…,A_{r_i})\) is good, and No otherwise.

样例1:

input:

7 3
3 -1 1 -2 2 0 5
2
1 6
2 7

output:

Yes
No

The sequence \(X:=(A_1 ,A_2,A_3 ,A_4 ,A_5 ,A_6 )=(3,−1,1,−2,2,0)\) is good. Indeed, you can do the following to make all elements equal \(0\).

  • First, do the operation with \(i=2,c=4\), making \(X=(3,3,5,2,2,0)\).

  • Next, do the operation with \(i=3,c=−2\), making \(X=(3,3,3,0,0,0)\).

  • Finally, do the operation with \(i=1,c=−3\), making \(X=(0,0,0,0,0,0)\).

Thus, the first line should contain Yes.

On the other hand, for the sequence \((A_2 ,A_3 ,A_4 ,A_5 ,A_6 ,A_7 )=(−1,1,−2,2,0,5)\), there is no way to make all elements equal \(0\), so it is not a good sequence. Thus, the second line should contain No.

样例2:

input:

20 4
-19 -66 -99 16 18 33 32 28 26 11 12 0 -16 4 21 21 37 17 55 -19
5
13 16
4 11
3 12
13 18
4 10

output:

No
Yes
No
Yes
No

AC代码:

#include <bits/stdc++.h>

using namespace std;

// 这个题可以通过一般形式来找规律
// 假设K = 3,有七个数A, B, C, D, E, F, G
// 假设N = 3,因为要让所有数都变为0,所以可以先让A变为0
// 所以操作后就变成0,B - A, C - A, 若是一个good数组,则此时B - A = 0 = C - A,得A = B = C
// 假设N = 4,一次操作后为0, B - A, C - A, D,第二次操作后为0, 0, C - B, A + D - B
// 此时可得C - B = 0 = A + D - B,即A + D = B = C
// 同理可得N = 5时,A + D = C = B + E
// 通过观察不难发现只要对于N个数,其不同下标i对K取模相等的数的和相同,那么就可以是一个good数组
// 或者不用找规律的方式来想
// 依旧是从前往后依次操作,如果是good数组,那么最后肯定会全是0,否则最后肯定会有某些数不是0
// 可以发现每次操作都会将下标对K取模为0 ~ K - 1这K个数大小同时改变,且改变的数值大小相同
// 那么也就是说不同下标i对K取模相等的数的和的大小也是同时发生改变,且改变数值大小相同
// 所以在最后一次操作的过程中,如果是good数组,那么最后所有数都变成0,和也变成0
// 如果最后某些数不是0,那么这些数的坐标i对K取模相等的数的和也不会是0
// 那么根据第16行分析可知,只有可能是因为和的大小和其他和的大小不同导致的
// 所有可得必须是下标i对K取模相等的数的和全相等,才会是good数组
int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    int n, k, q;
    cin >> n >> k;

    vector<int> a(n);

    for(int i = 0; i < n; i ++)
    {
        cin >> a[i];

        // 运用前缀和,将对K取模相等的加起来
        if(i >= k)
            a[i] += a[i - k];
    }

    cin >> q;

    while(q --)
    {
        int l, r;
        cin >> l >> r;

        l --, r --;

        vector<int> b(k);

        for(int i = r; r - i + 1 <= k; i --)
            b[i % k] = a[i];

        // 减去区间之外的
        for(int i = l - 1; i >= 0 && l - i <= k; i --)
            b[i % k] -= a[i];

        // 只有k个数,且这k个数都(与b[0])相等
        if(b == vector<int> (k, b[0]))
            cout << "Yes\n";
        else
            cout << "No\n";
    }

    return 0;
}

posted on 2023-02-06 19:07  KSzh  阅读(59)  评论(0编辑  收藏  举报