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