Codeforces#297 B Pasha and Strini

题意:给一个字符串,交换m次,每次交换a[i]~n-a[i]+1的字符(例如a[i]=2,n-5,则s[2]和s[4]换)。

思路:暴力时间复杂度是10^5*10^5,,pass。在交换中,我们可以先把多余的交换去掉。每个字符交换次数若为偶数,一定不变。为奇数,再交换一次即可。

用f[i]表示[i,n-i-1]段交换次数,n/2之后全部等价成1~n/2的。dp[i]表示每个字符交换的次数。注意字符串长度是奇数还是偶数,需分开讨论!

本题关键是找到每段字符串交换次数与每个字符交换次数的递推关系式:dp[i]=dp[i-1]+f[i]。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<set>#include<map>#include<vector>#include<cmath>#define ll __int64#define INF 0x3fffffff#define N 2*100005using namespace std;char s[N];int m;int a[N];int f[N];//[i,n-i-1]段交换次数int dp[N];//每位需交换次数int main(){//freopen("d:\\Test.txt","r",stdin);cin>>s;cin>>m;memset(f,0,sizeof(f));memset(dp,0,sizeof(dp));int n=strlen(s);for(int i=0;i<m;i++){cin>>a[i];}if(n%2==0){for(int i=0;i<m;i++){if(a[i]<=n/2){f[a[i]]++;}else{f[n-a[i]+1]++;}}dp[1]=f[1];for(int i=2;i<=n/2;i++){dp[i]=dp[i-1]+f[i];}}else{for(int i=0;i<m;i++){if(a[i]<n/2){f[a[i]]++;}else{f[n-a[i]+1]++;}}dp[1]=f[1];for(int i=2;i<=n/2;i++){dp[i]=dp[i-1]+f[i];}}for(int i=0;i<=n/2;i++){if(dp[i+1]&1) swap(s[i],s[n-i-1]);}cout<<s<<endl;return 0;}

摘抄美文4、承诺是一件美好的事情,但美好的东西往往不会变为现实。

Codeforces#297 B Pasha and Strini

相关文章:

你感兴趣的文章:

标签云: