bzoj 2789 逆序对

本文介绍了一种通过计算逆序对数量来解决字符串A如何通过相邻字符交换变为字符串B的问题。文中提供了详细的归并排序算法实现过程,并强调了处理相同字符的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出两个字符串A、B,只包含大写字母。每次交换A中相邻的两个字符,最少经过多少次变换可以变成字符串B,保证有解

两眼就可做的水题,水水更健康~

第一眼,答案妥妥的逆序对

第二眼,因为只包含大写字母所以一些位置上的字母是一样的,但是没有关系,因为同样的字符一定是按照顺序一一对应的,处理一下就可以了

然后归并排序或树状数组求逆序对

注意开long long

type
        rec=record
            last:longint;
end;

var
        n               :longint;
        i               :longint;
        ans             :int64;
        s1,s2           :ansistring;
        pre,a,c         :array[0..1000010] of longint;
        num             :array['A'..'Z'] of rec;
procedure merge_sort(l,r,mid:longint);
var
        t,i,j:longint;
begin
   i:=l; j:=mid+1; t:=l;
   while (t<=r) do
   begin
      if (i<=mid) and ((a[i]<=a[j]) or (j>r)) then
      begin
         c[t]:=a[i];
         inc(i);
         inc(t);
      end else
      begin
         c[t]:=a[j];
         inc(ans,mid-i+1);
         inc(j);
         inc(t);
      end;
   end;
   for i:=l to r do a[i]:=c[i];
end;

procedure merge(l,r:longint);
var
        mid:longint;
begin
   if (l<>r) then
   begin
      mid:=(l+r)>>1;
      merge(l,mid);
      merge(mid+1,r);
      merge_sort(l,r,mid);
   end;
end;

begin
   readln(n);
   readln(s1);
   readln(s2);
   for i:=1 to n do
   begin
      if (num[s1[i]].last<>0) then pre[i]:=num[s1[i]].last;
      num[s1[i]].last:=i;
   end;
   for i:=n downto 1 do
   begin
      a[i]:=num[s2[i]].last;
      num[s2[i]].last:=pre[num[s2[i]].last];
   end;
   //
   merge(1,n);
   writeln(ans);
end.
——by Eirlys



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值