• BZOJ 2789: [Poi2012]Letters 树状数组 + 逆序对


    Description

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

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

    Input

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

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

    Output

    一个非负整数,表示最少的交换次数。
    题解:求一个逆序对就完事了
    #include<bits/stdc++.h>
    #define setIO(s) freopen(s".in","r",stdin) 
    #define maxn 2000000 
    using namespace std;
    int n,m;
    int A[maxn],B[maxn];   
    char arr[maxn],brr[maxn]; 
    queue<int>q[30]; 
    struct BIT
    {
        int C[maxn]; 
        int lowbit(int t) { return t & (-t); }
        void update(int x,int delta) 
        {
            while(x<=m) C[x]+=delta,x+=lowbit(x); 
        }
        int query(int x) 
        {
            int tmp=0; 
            while(x>0) tmp+=C[x],x-=lowbit(x); 
            return tmp; 
        }
    }t; 
    int main()
    {
        // setIO("input");
        scanf("%d%s%s",&n,arr+1,brr+1); 
        int i,j; 
        for(i=1;i<=n;++i) A[i]=arr[i]-'A'+1; 
        for(i=1;i<=n;++i) B[i]=brr[i]-'A'+1; 
        for(i=1;i<=n;++i) q[B[i]].push(i);      
        for(i=1;i<=n;++i) 
        { 
            int c=A[i]; 
            A[i]=q[A[i]].front();  
            q[c].pop();    
        }  
        m=n; 
        long long re=0; 
        for(i=1;i<=n;++i) 
        { 
            re+=t.query(m)-t.query(A[i]); 
            t.update(A[i],1);    
        }
        printf("%lld
    ",re); 
        return 0;
    } 
    

      

  • 相关阅读:
    DOM事件模型
    Javascript 跨域
    浏览器内核及差异
    对WEB标准的理解
    SVN权限解析规则详解
    一款成熟的前端框架——Bootstrap
    终于可以发文了
    一些感想
    Linux升级nodejs及多版本管理
    zepto 自定义build
  • 原文地址:https://www.cnblogs.com/guangheli/p/11199254.html
Copyright © 2020-2023  润新知