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;
}