Pasha got a very beautiful string s for his birthday, the string consists of lowercase Latin letters. The letters in the string are numbered from 1 to |s| from left to right, where |s| is the length of the given string.
Pasha didn't like his present very much so he decided to change it. After his birthday Pasha spent m days performing the following transformations on his string — each day he chose integer ai and reversed a piece of string (a segment) from position ai to position|s| - ai + 1. It is guaranteed that 2·ai ≤ |s|.
You face the following task: determine what Pasha's string will look like after m days.
The first line of the input contains Pasha's string s of length from 2 to 2·105 characters, consisting of lowercase Latin letters.
The second line contains a single integer m (1 ≤ m ≤ 105) — the number of days when Pasha changed his string.
The third line contains m space-separated elements ai (1 ≤ ai; 2·ai ≤ |s|) — the position from which Pasha started transforming the string on the i-th day.
In the first line of the output print what Pasha's string s will look like after m days.
abcdef 1 2
aedcbf
vwxyz 2 2 2
vwxyz
abcdef 3 1 2 3
fbdcea
----------------- 思路:
转置与顺序无关,比如 1 2 3 4 5 和 5 4 3 2 1的转置顺序结果是一样的,所以先进行排序,删除成对的且相同的,同一部分转置两次相当于没转。 其实还可以简化,刚开始嫌麻烦就这样交了..于是超时了..刚好卡在最后一组数据上..于是要进一步优化,例如一个长度为10的串,输入 5 4 3 2 2 1 先排序,删掉两个2,剩下 1 3 4 5 。即 1-10,3-8,4-7,5-6 先看前两个,3-8 转了两次,所以只需要转置 1,2 与 9,10 即可。 同理,只要交换 4 与 7 即可。这样不仅运行次数减少了一半以上,而且每次执行的任务也大大减少了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn1=200000+100,maxn2=100000+100;
char str[maxn1]; ///全局变量!
int a[maxn2];
void reve(int p,int q) ///第一步优化,不用把数组作为参数加进来了
{
for(int i=p;i<=(p+q)/2;i++)
{
char c=str[i];
str[i]=str[p+q-i];
str[p+q-i]=c;
}
}
void change(int a,int b,int c,int d) ///第二步优化
{
for(int i=a;i<=b;i++)
{
char c=str[i];
str[i]=str[a+d-i];
str[a+d-i]=c;
}
}
int main()
{
while(~scanf("%s",str))
{
int len=strlen(str);
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
scanf("%d",a+i);
sort(a,a+m);
for(int i=0;i<m-1;i++) ///i<m-1
if(a[i]==a[i+1]&&a[i]!=0) a[i]=0,a[i+1]=0; ///a[i]!=0
int flag=2;
int k,t;
for(int i=0;i<m;i++)
{
if(a[i])
{
if(flag==2) flag--,k=a[i]-1; ///选出第一个没被删的数
else if(flag==1) flag--,t=a[i]-1; ///第二个没被删的数,这两个数一定不相等
}
if(!flag) change(k,t-1,len-t,len-k-1),flag=2; ///优化2
}
if(flag==1) reve(k,len-1-k); /// 是否存在落单的数
/// for(int i=0;i<m;i++)
/// if(a[i]) reve(a[i]-1,len-a[i]);
printf("%s\n",str);
}
return 0;
}