zoukankan      html  css  js  c++  java
  • 【BZOJ2789】[Poi2012]Letters 树状数组

    【BZOJ2789】[Poi2012]Letters

    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

    题解:首先对于B中的第一个字符,我们一定是贪心的选择A中最左边一个与它相同的字符移过来,并且移过来的过程中,其它字符的相对顺序不发生改变。所以我们只需要用树状数组维护每个字符被移动的距离,然后继续做下去即可。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int maxn=1000010;
    int n;
    long long ans;
    char A[maxn],B[maxn];
    int s[maxn],st[26][maxn],tp[26];
    void updata(int x,int v)
    {
    	for(int i=x;i<=n;i+=i&-i)	s[i]+=v;
    }
    int query(int x)
    {
    	int ret=0,i;
    	for(i=x;i;i-=i&-i)	ret+=s[i];
    	return ret;
    }
    int main()
    {
    	scanf("%d%s%s",&n,A+1,B+1);
    	int i,u;
    	for(i=n;i>=1;i--)	st[A[i]-'A'][++tp[A[i]-'A']]=i;
    	for(i=1;i<=n;i++)
    	{
    		u=st[B[i]-'A'][tp[B[i]-'A']--];
    		ans+=query(u)+u-i,updata(1,1),updata(u,-1);
    	}
    	printf("%lld",ans);
    	return 0;
    }
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    vue element 表单验证不通过,滚动到固对应位置
    vue源码之数据驱动
    vue源码之数据驱动
    vue源码之数据驱动
    每天一点点之数据结构与算法
    每天一点点之数据结构与算法
    python案例
    python案例
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7434635.html
Copyright © 2011-2022 走看看