问题标题: 再见了朋友~~&&3907怎么写不超时

0
0
已解决
李显晨
李显晨
中级启示者
中级启示者

我还是不忍心拿你的豆豆,这个数值代表了我的诚意,愿我们能再次相见@尤博扬

李显晨在2020-11-08 19:21:29追加了内容

错误代码

#include<iostream>
#include<cstdio>
#pragma GCC optimize(3)
using namespace std;
int a[400010],cnt;
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n-1;i++){
    	int flag=1;
    	for(int j=1;j<=n-i;j++){
    		if(a[j+1]<a[j]){
				cnt++;
    			swap(a[j+1],a[j]);
    			flag=0;
			}
		}
		if(flag) break;
	}
	printf("%d",cnt);
    return 0;
}

TLE 30分

李显晨在2020-11-08 19:23:29追加了内容

题目传送门

李显晨在2020-11-08 19:53:55追加了内容

@尤博扬 

 

李显晨在2020-11-09 16:02:20追加了内容

@尤博扬 

 


0
已采纳
尤博扬
尤博扬
初级光能
初级光能

@李显晨 

首先 这道题唯一不超时的方法是:用逆序数法

这种算法是高级算法 其他方法会决定超时 因为数据太大 给你看一下大佬的思路:

冒泡排序的复杂度是O(n2),所有无法通过模拟冒泡排序的过程来计算需要的交换次数。不过我们可以通过选取适当的数据结构来解决这个问题。

首先,所求的交换次数等价于满足i<j,ai>aj的(i,j)数对的个数(这种数对的个数叫做逆序数)。而对于每一个j,如果能够快速求出满足i<j,ai>aj的i的个数,那么问题就迎刃而解。我们构建一个值得范围是1~n的BIT,按照j=0,1,2,…,n-1的顺序进行如下操作。

*把j-(BIT查询得到的前aj项的和)加到答案中

*把BIT中aj位置上的值加1

对于每一个j,(BIT查询得到的前aj项的和)就是满足i<j,ai<=aj的i的个数。因此把这个值从j中减去之后,得到的就是满足i<j,ai>aj的i的个数。由于对于每一个j的复杂度是O(logn),所以整个算法的复杂度是O(nlogn)。

这个思路是来自百度的~~

PS:虽然他也给了代码,可是我完全看不懂 我也没有抄袭~~

————————————————————————

其次 心意我领了 下次再见了~~

0
0
郑金顺
郑金顺
中级光能
中级光能

静静地啃着狗粮,

厄玛,真香!

0
我要回答