n个数,每次可以让区间长度为k的一起增加x,询问m个范围,要求在范围内操作,使得该范围内所有数字变为0。

一开始看错题,以为让区间内输出变为相同了,做法是:区间加减,可以转成差分序列单点修改。为了让每一个数字变成第一个数字,我们想办法让差分序列变为0。不难发现,从左往右区间加x,最终差分序列变为0,实际上就是将位置模k相同的元素加起来,最后和为0即可。

由于题目要求全变为0,所以首个元素要必须是0,而不是跟前一个数字相等。让每个位置模k相等的数字加起来,和均相等即可,因为这样相当于差分序列对应位置和为零。

#include <stdio.h>
#define N 200050
int n, m, i, j, k, x, y, a[N];
long long s[N], p;
int main(){
    scanf("%d%d", &n, &k);
    for(i=1; i<=n; i++){
        scanf("%d", &a[i]);
        if(i > k) s[i] = s[i-k] + a[i];
        else s[i] = a[i];
    }//预处理模位置相同序列的前缀和 
    scanf("%d", &m);
    while(m--){
        scanf("%d%d", &x, &y);
        for(p=1e18, i=y-k+1; i<=y; i++){
            for(j=x-1; j>=1; j--){
                if(j%k == i%k) break;
            }//找到前面模相同的位置,没有取0 
            if(p > 1e17) p = s[i] - s[j];
            else if(p != s[i]-s[j]) break;
        }//后面出现的和均要与第一个相同 
        printf("%s\n", i>y?"Yes":"No");
    }
    return 0;
}

作者 crxis

发表回复