\(説明\)
\(スマート\)は、地球外からの秘密のメッセージを受け取りました。メール\(N \)首都英語の手紙を、残念ながら\(スマート\)メールの受信後には、誤って、元のアルファベット順を破壊しました。しかし、スマート\(スマート\)元のメッセージの内容を完全に覚えて、そして今、彼は電子メールに隣接する二つの手紙で動揺を交換した後、それぞれの時間を選択することができ、交換は倍の最小数は、メールの回復を妨害することができるようになります尋ねました元のメッセージに。
\(入力\)
最初の行\(1 \)整数\(n-は\)メッセージ長を表します。
長さの2行目\(n-は\)動揺した後、メッセージの文字列で表さのみ大文字が含まれています。
長さの第3行\(n-は\)のみ大文字は、元のメッセージ文字列を表す含ま。
動揺が元のメッセージに復元することができた後、メールを確実にするために、すべてのテストデータは、メールでの2つの大文字のいずれかの出現の同じ数を満たしています。
\(出力\)
交換の最小の整数を出力します。
\(サンプル入力1 \)
4
ABCD
DBCA
\(サンプル出力1 \)
5
\(ヒント\)
[データ範囲]
\(40%\)データ\(:n≤30\) 。
さらに\(20%\)データ\(N = 5000; \ )
\(100%\)データ\(:n≤1000000\) 。
\(解決\)
明らかに......とは逆の
大文字11の番号でメールの中断、その後、元のメッセージにマップします。
ここでは、同じイニシャルが発生した複数回表示され、その後、私たちは、最初は以前のマップで登場大文字を検討します
サンプルのように
\(ABCD \)
\(DBCA \)
\(1234 \)
の後にマッピングされた
\(4231 \)
、その後、答えは見つから\(4231 \)逆の順番の番号を
\((4,2)\) \(( 4,3)\) \((4,1)\) \((2,1)\) \((3,1)\)
番号はフェンウィックツリー求めて逆転するために使用することができます\(あるいは\) ......マージソート
ここでマージソートであります
#include<bits/stdc++.h>
#define Re register int
using namespace std;
vector<long long> W[27];
long long N,a[1000050],b[1000050],Now[27];
long long Ans;
char S_Mess[1000050],S_Last[1000050];
inline void merge_sort(int l,int r){
if(r-l>0){
int mid=(l+r)>>1;
int Wh=l;
int p=l,q=mid+1;
merge_sort(l,mid);
merge_sort(mid+1,r);
while(p<=mid || q<=r){
if(q>r || (p<=mid && a[p]<=a[q])) b[Wh++]=a[p++];
else{
b[Wh++]=a[q++];
Ans+=mid-p+1;
}
}
for(Re i=l; i<=r; i++) a[i]=b[i];
}
}
int main(){
scanf("%d",&N);
scanf("%s",S_Mess+1);
scanf("%s",S_Last+1);
for (Re i=1; i<=N; ++i) W[S_Last[i]-'A'+1].push_back(i);
for (Re i=1; i<=N; ++i) a[i]=W[S_Mess[i]-'A'+1][Now[S_Mess[i]-'A'+1]++];
merge_sort(1,N);
printf("%lld",Ans);
return 0;
}