2024年第九场蓝桥杯小白赛 字符迁移 知识点:差分

97 阅读1分钟

3.字符迁移【算法赛】 - 蓝桥云课 (lanqiao.cn)

思想

差分+前缀和

假设我们的区间刚开始全是0:

A:[0,0,0,0,0]

现在我们的l,r,k分别为2,4,4。

那么区间就变为:

B:[0,4,4,4,0]

我们直接维护这个区间加的操作,那么时间复杂度就和n的大小有关,是线性的复杂度。

差分数组是O(1)的复杂度,它只需要在两个端点处做修改即可:

C:[0,4,0,0,0,-4]

但是这样不是我们想要的结果,因此我们还需要求个前缀和,把差分数组恢复成B那样。

code

注意数据范围2e5,要开long long,不然数组存不下,会段错误

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+10;
LL b[N];

void insert(LL l,LL r,LL k)
{
	k=k%26; //防止右移超出z 
	b[l]+=k;
	b[r+1]-=k;
}
int main()
{
	int  n,m;cin>>n>>m;
	string s;cin>>s;
	while(m--)   //差分数组修改两个端点
	{
		LL l,r,k;
		cin>>l>>r>>k;
		insert(l,r,k);
	}
	    
       //前缀和恢复
	for(int i=1;i<=n;i++)b[i]+=b[i-1];
	
	//加回原数组
	for(int i=0;i<n;i++)
	{
		int temp=s[i]-'a';   //先变为整形
		temp=(temp+b[i+1])%26; //相加   temp是s[i],要加上后面的字符,所以是b[i+1]而不是b[i]
		s[i]=temp+'a';        //变为字符型 
	 } 
	
	cout<<s;
	return 0;
}