[bzoj2789]Letters

考虑A中第i次出现的j字符,最终位置一定是在B中第i次出现的j字符的位置,然后即求逆序对数量,cdq/线段树即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1000005
 4 #define L (k<<1)
 5 #define R (L+1)
 6 #define mid (l+r>>1)
 7 int n,a[N],c[N],nex[N],f[N<<2];
 8 long long ans;
 9 char s[N];
10 void update(int k,int l,int r,int x){
11     if (l==r){
12         f[k]++;
13         return;
14     }
15     if (x<=mid)update(L,l,mid,x);
16     else update(R,mid+1,r,x);
17     f[k]=f[L]+f[R];
18 }
19 int query(int k,int l,int r,int x,int y){
20     if ((l>y)||(x>r))return 0;
21     if ((x<=l)&&(r<=y))return f[k];
22     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
23 }
24 int main(){
25     scanf("%d%s",&n,s);
26     memset(c,-1,sizeof(c));
27     for(int i=n-1;i>=0;i--){
28         nex[i]=c[s[i]-'A'];
29         c[s[i]-'A']=i;
30     }
31     scanf("%s",s);
32     for(int i=0;i<n;i++){
33         a[c[s[i]-'A']]=i;
34         c[s[i]-'A']=nex[c[s[i]-'A']];
35     }
36     for(int i=0;i<n;i++){
37         ans+=query(1,0,n-1,a[i],n-1);
38         update(1,0,n-1,a[i]);
39     }
40     printf("%lld",ans);
41 }
View Code

 

posted @ 2019-08-07 19:55  PYWBKTDA  阅读(94)  评论(0编辑  收藏  举报