神奇到爆炸的贪心,策略很简单。但是实现上好像比较恶心。换了一种思路。先保存所有点应该转移到的位置,BIT搞个逆序对就好了。

如何找到每个点应该转移到的位置?这个处理方式也是比较玄学。看代码吧。

//OJ 1508
//by Cydiater
//2016.10.31
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n) 		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
#define cmax(a,b) 		a=max(a,b)
#define cmin(a,b)		a=min(a,b)
#define FILE "string!"
const int MAXN=1e6+5;
const int oo=0x3f3f3f3f;
char s[MAXN];
int N,pos[MAXN],cnt[MAXN],c[MAXN],Head[MAXN],Tail[MAXN],len=0;
struct _data{
	int v,next,pre;
}q[MAXN];
ll ans=0;
namespace solution{
	inline int lowbit(int i){return i&(-i);}
	inline int get(int Pos){int tmp=0;for(int i=Pos;i<=N;i+=lowbit(i))tmp+=c[i];return tmp;}
	inline void insert(int Pos){for(int i=Pos;i>=1;i-=lowbit(i))c[i]++;}
	void init(){
		scanf("%s",s+1);
		N=strlen(s+1);
		up(i,1,N){
			if(Head[s[i]]==0){
				Head[s[i]]=Tail[s[i]]=++len;
				q[len].pre=q[len].next=0;
				q[len].v=i;
			}else{
				q[Tail[s[i]]].next=++len;
				q[len].next=0;q[len].pre=Tail[s[i]];q[len].v=i;
				Tail[s[i]]=len;
			}
			cnt[s[i]]++;
		}
		bool flag=0;//pre judge
		up(i,'A','Z')if(cnt[i]%2==1&&(flag||N%2==0)){
			puts("-1");
			exit(0);
		}else if(cnt[i]%2==1)flag=1;
	}
	inline int get_siz(int i){
		if(Head[s[i]]==0)			return 0;
		if(Head[s[i]]!=Tail[s[i]])	return 2;
		else 						return 1;
	}
	void slove(){
		int j=1;
		up(i,1,N){
			int siz=get_siz(i);
			if(siz==0)continue;
			else if(siz==1){
				pos[q[Tail[s[i]]].v]=N/2+1;
				Head[s[i]]=Tail[s[i]]=0;
			}
			else{
				pos[q[Tail[s[i]]].v]=N-j+1;
				pos[q[Head[s[i]]].v]=j;
				if(q[Head[s[i]]].next==Tail[s[i]])Head[s[i]]=Tail[s[i]]=0;
				else{
					Head[s[i]]=q[Head[s[i]]].next;
					Tail[s[i]]=q[Tail[s[i]]].pre;
					q[Head[s[i]]].pre=0;q[Tail[s[i]]].next=0;
				}
				j++;
			}
		}
		up(i,1,N){
			ans+=get(pos[i]);
			insert(pos[i]);
		}
		cout<<ans<<endl;
	}
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	//freopen("input.in","r",stdin);
	//freopen("out.out","w",stdout);
	using namespace solution;
	init();
	slove();
	return 0;
}

[HAOI2009]求回文串的更多相关文章

  1. 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)

    2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...

  2. Palindrome - URAL - 1297(求回文串)

    题目大意:RT   分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的.   线段数+后缀数组代码如下: ...

  3. 马拉车,O(n)求回文串

    马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...

  4. manacher算法,求回文串

    用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...

  5. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...

  6. hihocoder 1032 manachar 求回文串O(n)

    #include <cstdio> #include <iostream> #include <algorithm> #include <queue> ...

  7. HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

    题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...

  8. LOJ 2452 对称 Antisymmetry——用hash求回文串数

    概念 用hash求最长回文串/回文串数 首先,易知,回文串具有单调性. 如果字符串 $s[l...r]$ 为回文串串,那么 $s[x...y]$($l < x, y < r$ 且 $|l- ...

  9. 拓展KMP求回文串

    题目:hdu3613: 题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0.求最大价值. 博客 分析:拓展KMP的应用求回文字串. #i ...

随机推荐

  1. flume:spooldir采集日志,kafka输出的配置问题

    flume配置: #DBFile DBFile.sources = sources1 DBFile.sinks = sinks1 DBFile.channels = channels1 # DBFil ...

  2. CDH离线数据导入solr:利用MapReduceIndexerTool将json文件批量导入到solr

    场景描述:前段时间,将实时数据通过kafka+flume+morphline的方式接入到solr中.新进来的数据已经可以在solr中看到了,但是以前的历史数据还没有导入solr. CDH提供利用Map ...

  3. BOOST.Asio——扫盲

    以下内容来自互联网. 鉴于版权之类的东西,我只贴出标题和URL. (无法考证下述资料是否原创.) asio串口编程                                            ...

  4. 1 张图秒懂 Nova 16 种操作 - 每天5分钟玩转 OpenStack(44)

    前面我们讨论了 Instance 的若干操作,有的操作功能比较类似,也有各自的适用场景,现在是时候系统地总结一下了. 如上图所示,我们把对 Instance 的管理按运维工作的场景分为两类:常规操作和 ...

  5. C# 注册表Regedit读写

    注册表的读写 1.读 public static string GetRegeditData() { //Win10 读写LocalMachine权限,没有访问权限 RegistryKey hkml ...

  6. shell脚本中生成延时

    #!/bin/bash echo -n count: tput sc count=; while true; do ]; then let count++; ; tput rc tput ed ech ...

  7. js中取得当前加载的js的src地址

    在很多js框架中看到过,如果要动态加载框架内部的其他js,加载的时候加载的地址经常是一个相对的地址,只能是这样了哦,因为框架根本不知道用此框架的用户,将框架js文件放的具体目录,所以框架中一般会采用如 ...

  8. 报表开发之批量导入导出excel

    在日常使用报表过程中,会有这样一种情况,你将Excel表分发给各个员工,员工填完后,统一整理成多个Excel,你需要将这些数据,用报表的填报功能,提交录入到数据库中,这样一来可避免到服务器机房录数据的 ...

  9. 一个开关电源传导、辐射处理案例-----Layout环路

    这是一款输入宽电压120-277V  60HZ,输出48V,273mA的电源,使用美芯晟MT7933,采用Buck拓扑结构. 注:在最初的设计中,预留电感L1.L2,CBB电容C1.C2作为传导测试元 ...

  10. Leetcode study time

    August 2, 2015 在http://zzk.cnblogs.com/ 用"找一找", 花了几个小时, 找出比较好的Leetcode博客. Read the leetcod ...