[HAOI2009]求回文串

时间:2023-03-10 06:49:56
[HAOI2009]求回文串

神奇到爆炸的贪心,策略很简单。但是实现上好像比较恶心。换了一种思路。先保存所有点应该转移到的位置,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;
}