题目描述
小美有一个由小写字母组成的字符串。小美认为字母表很有意思。所以他规定, 在小写字母中,每个字母的后继就是字母表中这个字母的后一个 , 比如 a 的后继是 b , b 的后继是 c 。而字母表中的最后一个字母是 z , 为了防止 z 没有后继 , 小美又规定 z 的后继是 a 。这样字母的后继就形成了一个 闭环。
现在小美想要让字符串发生变化。所以他 每次会给出一个 区间 和一个数 k , 并且让区间中所有的字母变成他们的第 k 个后继。第 k 个后继即让后继操作进行 k 次,比如 a 的 2 级后继是 c , a 的 26 级后继是 a 。
现在小美记下来了 操作序列和操作完之后得到的字符串 。请你 还原原来的字符串。
输入描述 :
第一行一个长度为 n (1 <= n <= 10^5) 的字符串 , 代表 操作完成 之后的字符串
第二行一个数 q (1 <= q <= 10^5) 代表操作次数
接下来 q 行 , 每行三个数 i , j , k ( 1 <= i <= j <= n , 1 <= k <= 10^9 ) , 代表区间 左右端点 和 第 k 级 后继。
输出描述:
输出一个字符串,代表操作之前小美的字符串。
样例输入:
abcdefg
3
1 3 1
2 4 1
3 5 2
样例输出:
zzyacfg
第一次操作后 : aazacfg
第二次操作后 : ababcfg
第三次操作后 : abcdefg
题目分析
此题的意思是:频繁对原始数组的某个区间的元素进行 同增 / 同减 ,符合差分数组的应用。 对差分数组不了的 可参考 差分数组模板 。
package baidu;
import java.util.*;
public class Main25 {
private int[] diff;
public void getDiff(int[] nums){
diff = new int[nums.length];
// 构造差分数组
diff[0] = nums[0];
for(int i = 1 ; i < nums.length ; i ++){
diff[i] = nums[i] - nums[i - 1];
}
}
// 给闭区间 [left , right] 增加 val (可以是负数)
public void increment(int left , int right , int val){
diff[left] += val;
if(right + 1 < diff.length){
diff[right + 1] -= val;
}
}
public String result(){
int[] res = new int[diff.length];
// 根据差分数组构造结果数组
res[0] = diff[0];
for(int i = 1 ; i < diff.length ; i ++){
res[i] = res[i - 1] + diff[i];
}
StringBuffer sb = new StringBuffer();
for(int i = 0 ; i < diff.length ; i ++){
// 正负数映射到区间 0-26 之间
int temp = ((res[i] % 26) + 26) % 26;
sb.append((char) ('a' + temp));
}
return sb.toString();
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String str = input.nextLine();
String num = input.nextLine();
int n = Integer.parseInt(num);
int len = str.length();
int[] nums = new int[len];
for(int i = 0 ; i < len ; i ++){
nums[i] = str.charAt(i) - 'a';
}
Main25 obj = new Main25();
obj.getDiff(nums);
while(n -- > 0){
String query = input.nextLine();
String[] buff = query.split(" ");
int left = Integer.parseInt(buff[0]);
int right = Integer.parseInt(buff[1]);
// 反向操作
int val = -Integer.parseInt(buff[2]);
obj.increment(left - 1 , right - 1 , val);
}
System.out.println(obj.result());
}
}