[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

 

转载于:https://www.cnblogs.com/PYWBKTDA/p/11273011.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值