首页 > 其他分享 >题解-[ABC288D] Range Add Query

题解-[ABC288D] Range Add Query

时间:2024-01-22 19:44:59浏览次数:24  
标签:int 题解 差分 a1 Range ABC288D 数组 区间 余数

题目:

[ABC288D] Range Add Query - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

大意:

一些数,选一个区间A(L~R),并再选一个区间B(长度k),这个区间B的每个数加减(加负数=减一个数)一个数,最终使得区间A全部数为0

举个例(样例)

0.    3 -1 1 -2 2 0

1.    0 -4 -2 -2 2 0  (-3)

2.    0 0 2 2 2 0   (+4)

3.    0 0 0 0 0 0   (-3)

所以最终为“Yes”(注意大小写问题)

 

思路:

刚开始就可以想到是差分了,因为是区间加减数,但是具体的不知道怎么做,也是想了比较久的时间的,很有意思

在解这题前得知道差分是什么(就是前缀和的逆)

然后要了解一个性质,例如有一个数列    (位:第几个数)

位1 2 3 4 5 6

值3 2 1 5 1 2

我们得让2~4的数加2,可以这样写

位1   2   3  4   5   6

值0 +2   0  0  -2   0  

这样的话这个区间也算是每项加2了,因为第2位加了2,后面的会跟着加2,但是在第4位加完2,第5位得减回来,不然会超出范围

前置知识了解完就可以看思路了

 

 

最终,A数组加减一堆数,肯定全为0了(输出Yes的情况),那么B数组也会变成{-a1, 0, 0, 0.... 0}。由于我们要选长度为k的区间B,考虑加减一个数。所以每个数(A数组)可以对应一个余数(%k),来方便我们找规律,如下

A数组 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12
余数  1  2  3  4   1 2  3  4  1   2  3    4
B数组 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12
B最终 -a1 0 0  0  0  0  0  0  0   0  0    0



这里我们定,s[i][j]表示前i个数余数为j的差分数组的和,会发现有3种情况,区间内同余数和一定为0,肯定相同,但是还有左右端点要特判,所以分情况

情况1,当下标为i=(R+1)%k     L+b[L]==0                          在区间内,自然的
情况2,当下标为i==L mod k    S[R][余]-s[L-1][余]==-a[L-1]        像b[1]最终为-a1一样,不过这里的位置不固定,换成a[L-1]
情况3,当下标i区间L,R内      s[R][余]-s[L-1][余]==0              在区间外没余数这个值了




具体可以看代码,里面的注释也很详细了
#include <bits/stdc++.h>
using namespace std;

const int N=2e5+5, M=11;
int n, k, a[N], b[N], s[N][M], m, L, R;
//s[i][j]:前i个数余数为j的差分数组的和
//b:差分数组 
int yu(int x) //求余 例如4%3=1, 4%4=4 
{
	return (x-1)%k+1;
}
int main()
{
	scanf("%d%d", &n, &k);
	for (int i=1; i<=n; i++) 
	{
		scanf("%d", &a[i]);
		b[i]=a[i]-a[i-1];
	}
	//b最终:  -a1 0 0 0 ... 0 
	for (int i=1; i<=n; i++)
	{
		for (int j=1; j<=k; j++) s[i][j]=s[i-1][j]; //余数相等,必然有 i=i-1
		s[i][yu(i)]+=b[i]; //余数不同,加上此差分数组的数 
	}
	scanf("%d", &m);
	while (m--)
	{
		int flag=0;
		scanf("%d%d", &L, &R);
		for (int i=L; i<=L+k-1; i++) //遍历区间,不用全部跑,因为余数最多为L+k-1 
		{
			int j=yu(i);
			if (j==yu(R+1)) continue;//情况1不考虑,因为b数组都为0,在区间内无影响
			
			if (j==yu(L)) //情况2 
			{
				if (s[R][j]-s[L-1][j]!=-a[L-1]) 
				{
					flag=1;
					break;
				}
			} 
			else //情况3 
			{
				if (s[R][j]-s[L-1][j]!=0) 
				{
					flag=1;
					break;
				}
			}
		
		
		}	
		if (flag==1) printf("No\n");
		else printf("Yes\n");
	}
	return 0;
}
/*
A数组 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12
余数  1  2  3  4   1 2  3  4  1   2  3    4
B数组 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12
B最终 -a1 0 0  0  0  0  0  0  0   0  0    0
区间     2                       10              (选2~10)
         2           2            2             情况2,当下标为i==L mod k    S[R][余]-s[L-1][余]==-a[L-1] 
            3          3            3           情况1,当下标为i=(R+1)%k     L+b[L]==0
               4           4              4     情况1,同上 
                  1           1					情况3,当下标i区间L,R内      s[R][余]-s[L-1][余]==0 
*/

  

 

第一次写题解,有不足请指出,谢谢!

标签:int,题解,差分,a1,Range,ABC288D,数组,区间,余数
From: https://www.cnblogs.com/didiao233/p/17980826

相关文章

  • 2024 蓝桥杯模拟赛 1 (div1) 题解
    A.把字符串小写转换成大写即可#include<bits/stdc++.h>usingnamespacestd;voidsolve(){strings;cin>>s;for(inti=0;i<s.size();i++){if(s[i]>='a'&&s[i]<='z'){s[i]=(char)(s[i]-'a......
  • 2024 省选联测部分题解
    目录目录R15T1树V图R15T2矩阵缺失题目:R15T3.R15T1树V图原题:SNOI2024D1T1.注意到答案肯定是形如每个连通块选一个点组成,把连通块缩起来后令\(dp_{u,x}\)表示连通块\(u\)选\(x\)的方案数,每次合并子树转移即可.因为只有\(n^2\)个合法点对所以时间复杂度......
  • R语言包安装失败常见问题解决
    更改或指定镜像源出现这个问题很有可能是你现在用的镜像中未纳入这个包,一是可以多换个源试试。如:install.packages('package-name',repos='http://cran.us.r-project.org')或,在Rstudio中可以:或,命令行可直接指定Rstudio:install.packages('package_name',dependencies=TRUE......
  • 【问题解决】Kafka报错 Bootstrap broker x.x.x.x:9092 (id: -1 rack: null) disconne
    【问题解决】Kafka报错Bootstrapbrokerx.x.x.x:9092(id:-1rack:null)disconnected和服务器连接已经断开。可能kafka服务器停止问题复现近日针对某一客户需求开发了一个需要使用Kafka的功能,功能是什么暂且不论,在本地虚机的Kafka连接一切正常遂放到测试服务器上验证功......
  • Kafka【问题 02】KafkaTemplate 报错 Bootstrap broker localhost:9092 (id: -1 rack:
    Kafka【问题02】KafkaTemplate报错Bootstrapbrokerlocalhost:9092(id:-1rack:null)disconnected问题解决1.报错信息主要的报错信息:Connectiontonode-1(localhost/127.0.0.1:9092)couldnotbeestablished.Brokermaynotbeavailable.和Bootstrapbrok......
  • CF1920E 题解
    CF1920E被这种题卡了,脸都不要了。仔细读题,发现序列可以分成两部分(\(0\)和\(1\))来考虑。在合法序列中,对于一个\(1\),它产生的子串贡献一定是(假设与上一个\(1\)之间有\(x\)个\(0\),与下一个\(1\)之间有\(y\)个\(0\)):\[(x+1)(y+1)\]如果去DP这\(n\)个\(1\),易得转......
  • CF455D Serega and Fun 题解
    题目链接:CF或者洛谷本题是可以用平衡树去做的,具体的为每个\(k\)开一棵平衡树去维护相对位置,而这种移动操作用平衡树维护又是很容易做到的,这种做法是双\(log\)。在\(1e5\)的数据下,我们来说说好写的分块该如何去写。黑色的代表一个块,考虑暴力修改情况,假如原来的数字为\([1......
  • 决斗 题解
    决斗题解赛题来自OIFHA第四场模拟赛。原题展现青蛙哥与名侦探柯南正在进行一场对决。他们两个人每人有\(n\)张牌,每张牌有一个点数。并且在接下来的\(n\)个回合中每回合青蛙哥与名侦探柯南两人会各自打出一张牌。每回合裁判会检查,打出的牌点数更高的一方获胜从而得到......
  • UVA10295 Hay Points 题解
    题目大意:给你\(n\)个单词,每一个单词的值为\(v_i\),让你求出在一个文章段落里的出现过的单词的值之和。思路:可以用STL库中的map来存储一个单词的值,最后在处理的时候可以直接累加。附上你们最期待的代码:#include<bits/stdc++.h>usingnamespacestd;map<string,int......
  • AT_arc169_a的题解
    关于我在赛场上一题都没有切,后面自己推出来正解这件事~题面翻译给定一个长度为\(N\)的整数序列\(A=(A_1,A_2,\cdots,A_N)\)和另一个长度为\(N-1\)的整数序列\(P=(P_2,\cdots,P_N)\)。注意\(P\)的索引从\(2\)开始。对于每个\(i\),保证\(1\leqP_i<i\)。现在您......