bzoj 2789: [Poi2012]Letters
2016-05-03 09:09
441 查看
2789: [Poi2012]Letters
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 297 Solved: 197
[Submit][Status][Discuss]
Description
给出两个长度相同且由大写英文字母组成的字符串A、B,保证A和B中每种字母出现的次数相同。现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B。
Input
[align=left][/align]第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度。
第二行和第三行各一个长度为n的字符串,并且只包含大写英文字母。
Output
[align=left]一个非负整数,表示最少的交换次数。[/align]Sample Input
3ABC
BCA
Sample Output
2HINT
ABC -> BAC -> BCASource
鸣谢 oimaster[Submit][Status][Discuss]
题解:权值树状数组求逆序对。
预处理的时候把第一个字符串顺序编号,然后第二个字符串中的字符找到他在第一个串中的位置,并记录。
最后对第二个串记录下来的序列求逆序对。
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #define N 1000003 using namespace std; int n,ch[30][100000],len ,pd[30]; long long tr ,ans; char s ,s1 ; int lowbit(int x) { return x&(-x); } void change(int x,long long v) { for (int i=x;i<=n;i+=lowbit(i)) tr[i]+=v; } long long sum(int x) { int ans=0; for (int i=x;i;i-=lowbit(i)) ans+=tr[i]; return ans; } int main() { scanf("%d\n",&n); scanf("%s",s+1); scanf("%s",s1+1); for (int i=1;i<=n;i++) { int x=s[i]-'A'; ch[x][++ch[x][0]]=i; } for (int i=1;i<=n;i++) { int x=s1[i]-'A'; pd[x]++; len[i]=ch[x][pd[x]]; } for (int i=n;i>=1;i--) { ans+=sum(len[i]); change(len[i],1); } printf("%lld\n",ans); }
相关文章推荐
- oracle的触发器
- Android 存储记录
- jq垂直下拉菜单
- swift开发多线程篇 - 多线程基础
- 【 Zabbix 】— 监控系统搭建
- OSChina 周二乱弹 ——一个良好的生活习惯能拯救你的人生
- 先到大企业“潜伏” 再去地图边缘创业
- 线程和进程的区别
- 多个storyboard实现tabbar
- SQLSERVER维护计划报告和记录
- 20160502-struts2入门--ognl表达式
- 设置JavaScript自动提示-Eclipse/MyEclipse
- 接口
- pdo预处理案例
- JavaScript中常用的正则表达式
- 分布式环境中的负载均衡策略
- Android 6.0 运行时权限处理
- fragment 碎片整理
- 响应式网格视图css
- ABSTRACT FACTORY抽象工厂 - 对象创建型模式(四)