• Bzoj 2789: [Poi2012]Letters 树状数组,逆序对


    2789: [Poi2012]Letters

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 278  Solved: 185
    [Submit][Status][Discuss]

    Description

    给出两个长度相同且由大写英文字母组成的字符串A、B,保证A和B中每种字母出现的次数相同。

    现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B。

     

    Input

     

     

    第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度。

    第二行和第三行各一个长度为n的字符串,并且只包含大写英文字母。

     

     

    Output

    一个非负整数,表示最少的交换次数。

    Sample Input

    3
    ABC
    BCA

    Sample Output

    2

    HINT


     

    ABC -> BAC -> BCA

     

    Source

    鸣谢 oimaster

    题解:

    树状数组+逆序对

    口胡 :Bzoj好像挂了QAQ,好伤心555555

    好了,开始说正题。

    首先,最少次数交换相邻的元素之类的肯定用树状数组求逆序对。然后考虑贪心。

    这道题的贪心思路很好想,就是把B数列每个数把其在A数列中最近的数移过来。

    例如:

    A数列 : ABACA

    B数列 : ABCAA

    对于B数列中每个数,我们去找在A数列中应该出现的位置,若字母相同就往后找,直到找到第一个没有在A数列中选过的位置。

    则上述例子可以得到数列:1 2 4 3 5

    然后逆序对胡搞。。。

    具体看程序,自己手推一下就懂了 ^w^

    PS:把int变量定到char类型中也是爽。。。QAQ

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 #define LL long long
     9 #define MAXN 1000010
    10 struct node
    11 {
    12     int v,w;
    13 }a[MAXN],b[MAXN];
    14 /*struct NODE
    15 {
    16     int v,w;
    17 }b[MAXN];*/
    18 int n;
    19 int BIT[MAXN],c[MAXN];
    20 char A[MAXN],B[MAXN];
    21 bool cmp(node aa,node bb)
    22 {
    23     if(aa.v==bb.v)return aa.w<bb.w;
    24     return aa.v<bb.v;
    25 }
    26 /*bool cmp1(NODE aa,NODE bb)
    27 {
    28     if(aa.v==bb.v)return aa.w<bb.w;
    29     return aa.v<bb.v;
    30 }*/
    31 int Lowbit(int o){return o&(-o);}
    32 void Update(int o,int o1)
    33 {
    34     while(o<=n)
    35     {
    36         BIT[o]+=o1;
    37         o+=Lowbit(o);
    38     }
    39 }
    40 int Sum(int o)
    41 {
    42     int sum=0;
    43     while(o>0)
    44     {
    45         sum+=BIT[o];
    46         o-=Lowbit(o);
    47     }
    48     return sum;
    49 }
    50 int main()
    51 {
    52     int i;
    53     LL ans=0;
    54     scanf("%d",&n);
    55     scanf("
    %s
    %s",A+1,B+1);
    56     for(i=1;i<=n;i++)
    57     {
    58         a[i].v=A[i]-'A'+1;b[i].v=B[i]-'A'+1;
    59         a[i].w=b[i].w=i;
    60     }
    61     sort(a+1,a+n+1,cmp);
    62     sort(b+1,b+n+1,cmp);
    63     for(i=1;i<=n;i++)c[a[i].w]=b[i].w;
    64     memset(BIT,0,sizeof(BIT));ans=0;
    65     for(i=n;i>=1;i--)
    66     {
    67         ans+=Sum(c[i]-1);
    68         Update(c[i],1);
    69     }
    70     printf("%lld",ans);
    71     fclose(stdin);
    72     fclose(stdout);
    73     return 0;
    74 }
  • 相关阅读:
    Map基础知识01-ConcurrentHashMap
    数据结构基础03-红黑树
    vue element 表格增加删除修改数据
    好用弹出层
    如何给网页添加水平线
    如何搭建一个vue项目的详细步骤
    vue完成项目后,如何打包成静态文件
    jQuery 每隔5秒钟发送一个ajax请求 请求后台数据接口
    windows远程桌面连接提示身份验证错误,要求的函数不受支持的解决方法
    uniapp安卓app打包后获取位置信息失败解决方法(含高德地图key详细申请流程)
  • 原文地址:https://www.cnblogs.com/Var123/p/5339336.html
Copyright © 2020-2023  润新知