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