官方题解:https://media.hihocoder.com/contests/challenge34/tutorials-previewed.pdf

题目链接:http://hihocoder.com/problemset/problem/1781

题意问对于给定序列A,是否存在一个整数k, 使得A冒泡k轮后变成序列B.

这题一种做法是像官方题解一样写个计算区间最值的数据结构。

而我是另一种做法,通过的逆序数 来判断A怎样能变化到B。

例子

首先我举一个例子:

对于序列  A

8 7 5 1 9 2 6 4 3

其每个位置的逆序数是:

0 1 2 3 0 4 3 5 6       (*)

接着对A冒泡一轮,得到:

7 5 1 8 2 6 4 3 9

这时每个位置的逆序数是:

0 1 2 0 3 2 4 5 0      (**)

那么序列(*)和序列(**) 直接有啥联系呢?

(**)=(*)每个数减-1,并向左平移一格 ,且最多减到0.

证明

现在来证明,每冒泡一轮 所有位置的逆序数-1,并向左移一格。

引理1:对于每轮冒泡排序,若一个位置的前面存在比他大的数,  则他一定会他前面的某个比他大的数进行有且仅有一次交换

这个引理大家自已脑补一下,应该很容易理解是对的。

引理2:若一个位置的前面存在比他大的数,则个位置的逆序数大于0

这个废话,我就不解释了。

证:因为任意一个逆序大于1位置,都与比他大的数交换一次,交换后首先逆序数必然减一,其次,交换后为位置肯定前移1格。 故结论成立。

解题思路

有了这个规律,显然我可以直接O(n)求出任意一轮A的逆序数 与B比较。

再利用【逆序数和】每轮的都会递减的单调性。就可以用二分比较逆序数和的方式,在O(n logn)时间定位b.

或者做一个O(n)预处理,算出n-1轮中,每轮的逆序数和,这样可以把查询的时间复杂度降低至O(n)

当然因为还要对数据进行O(n logn)离散化和求逆序数的原因,所以无论你写哪种最终复杂度都是O(n logn)。

 #include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
#include<stack>
#include<math.h>
using namespace std;
#define lowbit(x) (x&(-x))
int a[],b[];
int s1[],s2[];
int c[];
int N=;
int cot[];
int getsum(int x)
{
int sum=;
while(x)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void add(int x)
{
while(x<=N)
{
c[x]++;
x+=lowbit(x);
}
}
vector<int>que;
int getid(int x)
{
return lower_bound(que.begin(),que.end(),x)-que.begin()+;
}
void cal(int n,int a[],int ans[])
{
int i;
memset(c,,sizeof(c));
for(i=; i<=n; i++)
{
ans[i]=(i-)-getsum(a[i]);
add(a[i]);
}
}
int main()
{
int i,j,t,n,x,y,k,op,q;
long long m;
// freopen("1.in","r",stdin);
//freopen("2.out","w",stdout);
scanf("%d",&t);
for(int cas=; cas<=t; cas++)
{
scanf("%d",&n);
memset(s1,,sizeof(s1));
memset(cot,,sizeof(cot));
que.clear();
for(i=; i<=n; i++)
{
scanf("%d",&a[i]);
que.push_back(a[i]);
}
for(i=; i<=n; i++)
{
scanf("%d",&b[i]);
que.push_back(b[i]);
}
sort(que.begin(),que.end());
m=unique(que.begin(),que.end())-que.begin();
que.resize(m);
int ans=-;
for(i=; i<=n; i++)
{
a[i]=getid(a[i]);
b[i]=getid(b[i]);
}
cal(n,a,s1);
cal(n,b,s2);
long long sum=;
k=;
for(i=; i<=n; i++)
{
cot[s1[i]]++;
k=max(s1[i],k);
sum+=s2[i];
printf("%d ",s1[i]);
}
m=;
for(i=k+; i>; i--)
{
m=m+cot[i];
sum-=m;
if(sum<=)
{
break;
}
}
if(sum==)
{
i--;
for(j=; j<=n; j++)
{
if(max(s1[j+i]-i,)!=s2[j])
{
break;
}
}
if(j>n)
{
sort(a+,a+n+);
sort(b+,b+n+);
for(j=; j<=n; j++)
{
if(a[j]!=b[j])
{
break;
}
}
if(j>n)
{
ans=i;
}
}
}
printf("Case #%d: %d\n",cas,ans);
}
return ; }

AC代码

hihoCoder挑战赛34 B题(快速求第k轮冒泡排序的结果)的更多相关文章

  1. hihoCoder挑战赛1 毁灭者问题

    题目链接:http://hihocoder.com/problemset/problem/1034 数据结构题,由于每个魔法单位有着不同的回复速度和上限,所以不能根据吸收时间点进行查询和更新.但是如果 ...

  2. hihoCoder挑战赛23

    hihoCoder挑战赛23 A.Emulator 题意 给一张图,有\(N(N \le 300)\)个点, 给出任意两点之间的最短路. 求最多可以去掉多少条边,使得任意两点的最短路长度不变. 思路 ...

  3. 快速求幂(Quick Exponentiation)

    接触ACM没几天,向各路大神求教,听说ACM主要是研究算法,所以便开始了苦逼的算法学习之路.话不多说,RT所示,学习快速求幂. 在头文件<math.h>或是<cmath>中,d ...

  4. NYOJ--102--次方求模(快速求幂取模)

    次方求模 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 求a的b次方对c取余的值   输入 第一行输入一个整数n表示测试数据的组数(n<100)每组测试只有一 ...

  5. poj 2001:Shortest Prefixes(字典树,经典题,求最短唯一前缀)

    Shortest Prefixes Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12731   Accepted: 544 ...

  6. poj 1004:Financial Management(水题,求平均数)

    Financial Management Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 126087   Accepted: ...

  7. 快速求n的质因子(数论)

    快速求n的质因子 如何尽快地求出n的质因子呢?我们这里又涉及两个好的算法了! 第一个:用于每次只能求出一个数的质因子,适用于题目中给的n的个数不是很多,但是n又特别大的 #include<std ...

  8. 阿里聚安全攻防挑战赛第三题Android PwnMe解题思路

    阿里聚安全攻防挑战赛第三题Android PwnMe解题思路 大家在聚安全挑战赛正式赛第三题中,遇到android app 远程控制的题目.我们今天带你一探究竟,如何攻破这道题目. 一.题目 购物应用 ...

  9. 【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)

    问题描述: 林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感.于是林记决定:以后出题,答案一 ...

随机推荐

  1. Linux YUM (Yellowdog Updater, Modified) Commands for Package Management

    Linux YUM (Yellowdog Updater, Modified) Commands for Package Management In this article, we will lea ...

  2. CONDENSE命令により、文字列から冗長スペースが削除

    CONDENSE 命令により.文字列から冗長スペースが削除されます. CONDENSE c [NO-GAPS]. この命令により.項目 c に先行空白が含まれる場合は削除され.その他の空白列がある場合 ...

  3. 笔记-restful

    笔记-restful 1.      restful简介 restful:representational state transfer,简称REST,描述了一个架构样式的网络系统. 值得注意的是RE ...

  4. 03,Python网络爬虫第一弹《Python网络爬虫相关基础概念》

    爬虫介绍 引入 为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的应用还是从就业上. 我们都知道,当前我们所处的时代 ...

  5. 腾讯QQ空间穿越时光轴3D特效

    <DOCTYPE html> <html> <head> <title>腾讯QQ空间穿越光轴3D特效</title> <style&g ...

  6. 《Cracking the Coding Interview》——第11章:排序和搜索——题目4

    2014-03-21 21:28 题目:给定一个20GB大小的文本文件,每一行都是一个字符串.请设计方法将这个文件里的字符串排序. 解法:请看下面的注释. 代码: // 11.4 Given a fi ...

  7. 基于Python的selenuim自动化测试尝试

    工作这么多年了,终于狠下心好好开始学学自动化测试相关知识,揭开这层神秘的面纱. 困难重重,障碍很多,但好在每天都多少有点小收获. 很感谢一个QQ好友推荐的虫师,也非常感谢在这个契机读到了虫师编著的&l ...

  8. Python 实现MD5加密

    from hashlib import md5 def encrypt_md5(s): # 创建md5对象 new_md5 = md5() # 这里必须用encode()函数对字符串进行编码,不然会报 ...

  9. React01

    目录 React-day01 入门知识 React介绍 官网 React开发环境初始化 SPA 脚手架初始化项目(方便,稳定)* 通过webpack进行初始化 配置镜像地址 开发工具配置 元素渲染 组 ...

  10. js万年历

    首先,注意: 1.延迟执行     window.setTimeout(    ,     )     里面的时间是以毫秒计算的 2.间隔执行    window.setInterval(     , ...