【题目】E - Papple Sort

【题意】给定长度为n的小写字母串,只能交换相邻字母,求形成回文串的最小步数。n<=2*10^5。

【算法】数学

【题解】官方题解

本题题解中有以下重要的思想:

①分析多复杂因素相互干扰的问题时,先排除无关因素,然后转化关联因素为独立因素后逐个分析。

②位置移动的问题中,常用转绝对位置为相对位置,考虑两两相对的情况。

③回文的性质:嵌套。

奇数串和偶数串对做法没有影响,忽略。

首先,对于串中所有字母x,交叉移动没有任何意义,所以一定是最左-最右,次左-次右...的组合。这样我们可以将长度为n的串视为n/2对字母。

现在,考虑串中任意两对字母AA和BB的相对位置和对应交换策略

1.[...A...A...B...B...],A作为外围字母(A移动到B右边对称位置)和B作为外围字母(B移动到A左边对称位置)移动距离一致,无影响。

2.[...A...B...A...B...],移动距离一致,无影响。

3.[...A...B...B...A...],A-A必须作为外围字母而B-B必须作为内围字母。

注意:这里很容易认为在前两种情况中,A移动还是B移动会对中间省略号的部分造成影响。但是请注意这里是只考虑A-A和B-B这两对的相对位置,从A必须相对于B-B回文而不是全局回文也可以看出。在每次移动都会牵扯很多数字的情况下,我们刻意不在所有数字都存在的全局范围内讨论移动,而是单独考虑两两对之间的位置和对应策略,这样就不会有全局的复杂关联因素。

综上所述,为了保证不会发生第三种情况的内越外,当(l1,r1)和(l2,r2)满足l1<l2时,(l1,r2)必须是外围字母。

因此,必须从左往右做,每次将对应字母移动到回文位置,这样就能保证所有(l2,r2),l1>l2的r2都在最外围(不会越过),而会越过所有(l2,r2),l1<l2的r2。

提前判断无解后,统计步数用树状数组记录当前剩余元素来实现(每次都视为移动到n,移动过的元素在最外围直接删除)。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=; int n,c[maxn],num[maxn];
bool vis[maxn];
char s[maxn];
vector<int>v[];
void modify(int x,int k){for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;}
int query(int x){int ans=;for(int i=x;i>=;i-=lowbit(i))ans+=c[i];return ans;}
int main(){
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++)num[s[i]-'a']++,v[s[i]-'a'].push_back(i);
int ok=;
for(int i=;i<;i++){
if(num[i]%)ok++;
}
if(ok>){printf("-1");return ;}
for(int i=;i<=n+;i++)modify(i,);
ll ans=;
for(int i=;i<=n;i++)if(!vis[i]){
int c=s[i]-'a';
int x=v[c][v[c].size()-];
if(i==x){
ans+=(query(n)-query(i))/;
}
else{
ans+=(query(n)-query(x));
}
modify(i,-);modify(x,-);
vis[i]=vis[x]=;
v[c].erase(v[c].end()-);
}
printf("%lld",ans);
return ;
}

【Atcoer】ARC088 E - Papple Sort的更多相关文章

  1. 【AtCoder】ARC088

    C - Multiple Gift 题解 首项是X,每次乘个2,暴力统计 代码 #include <bits/stdc++.h> #define fi first #define se s ...

  2. 【Atcoder】ARC088 D - Wide Flip

    [题目]D - Wide Flip [题意]给定n个数字的01序列,要求每次翻转>=k个数字使得全0,求最大的k.n<=10^5 [算法]数学 [题解]有两个角度可以得到等价的结论: 1. ...

  3. 【转】 std list/vector sort 排序

    [转自]http://blog.csdn.net/marising/article/details/4567531 网上江湖郎中和蒙古大夫很多,因此,此类帖子也很多.关于排序,我还真没研究过,看了江湖 ...

  4. 【转载】双调排序Bitonic Sort,适合并行计算的排序算法

    双调排序是data-independent的排序, 即比较顺序与数据无关的排序方法, 特别适合做并行计算,例如用GPU.fpga来计算. 1.双调序列 在了解双调排序算法之前,我们先来看看什么是双调序 ...

  5. 【转】linux中的sort命令

    转自:http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分 ...

  6. 【转载】C#中自定义Sort的排序规则IComparable接口

    C#中的List集合在排序的时候,如果不使用Lambda表达式进行排序的话,一般调用Sort()方法进行排序,如果希望Sort()方法排序后的结果跟我们预想的效果一致或者按照我们自定义的规则排序,则需 ...

  7. 【算法】插入排序(Insertion Sort)

    (PS:内容参考MIT算法导论) 插入排序(Insertion Sort): 适用于数目较少的元素排序 伪代码(Pseudocode): 例子(Example): 符号(notation): 时间复杂 ...

  8. 【HackerRank】 The Full Counting Sort

    In this challenge you need to print the data that accompanies each integer in a list. In addition, i ...

  9. 【JS】297-[译]正确使用 sort() 方法

    点击上方"前端自习课"关注,学习起来~ 英文原文:[<Usar correctamente el método sort()>]文章地址:查看阅读原文.注意:内容有做精 ...

随机推荐

  1. erlang中检查内存泄露

    最近项目内存占用过多,检查一下erlang的内存使用情况. 1. 通过etop可以很方便得出erlang内存使用的情况 spawn(fun() -> etop:start([{output, t ...

  2. web移动端

    h5:低版本(IE8及以下不支持H5标签,要引入html5shiv.js才能正常运行) 条件引入,只是针对PC端,移动端不存在这样的操作 <figure>:专门用来存放图片和相关介绍的 & ...

  3. Objective - C 之类目

    一.类目(category):为已有的类(可以是系统类,也可以是自定义类)添加公有的新的方法: 例如:为系统已有的NSString类添加一个比较字符串大小的方法 1.创建过程: 2.NSString ...

  4. 补发9.26“天天向上”团队Scrum站立会议

    组长:王森 组员:张金生 张政 栾骄阳 时间:2016.09.26 地点:612寝 组员 已完成 未完成 王森 可行性分析 找出设计亮点 张金生 寻找UI素材 设计用户操作 张政 搭建环境 基础逻辑框 ...

  5. 反向代理负载均衡-----nginx

    一:集群 1.1:集群的概念    集群是一组相互独立的.通过高速网络互联的计算机,他们构成了一个组,并以单一系统的模式加以管理.一个客户与集群相互作用时,集群像是一个独立的服务器.集群配置是用于提高 ...

  6. POJ2823_Sliding Window

    以前也碰到过这种类型的题目,以前好像做出来过,但是忘记了,这次又坑了. 题目很简单,对于从前到后每一个连续的长度为k的数字,求出这段数字中的最大的数字和最小的数字. 一开始我用离散化+树状数组来更新和 ...

  7. 【bzoj5197】[CERC2017]Gambling Guide 期望dp+堆优化Dijkstra

    题目描述 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易时,你可以选择 ...

  8. 【JavaScript】jsp表格页面记录

    页面效果如下: jsp代码如下(里面引入了很多其他js文件,很多方法调用来自其他js): <%@ page language="java" contentType=" ...

  9. jQuery绑定事件

    1.事件绑定的方式 事件 DOM:三种绑定方式 jQuery: #前面几种内部调用的全是on $('.c1').click() $('.c1').blur() $('.c1').aaaaa() $(' ...

  10. 【转】NHibernate主键类型介绍

    转自:http://blog.163.com/wzx_dd/blog/static/1942850722012828934553/ 最近整合了一下框架,用SSH搭建了一个框架,但是在整合好之后,启动t ...