您的位置:首页 > 大数据 > 人工智能

2016 Multi-University Training Contest 4 1012 Bubble Sort (线段树)

2016-09-08 16:10 351 查看

题意

给出一个序列,问在冒泡排序的过程中,每个数到达的最左和最优位置之差是多少。

思路

观察发现,根据题目给的算法,每个数的最左位置就是他的最终位置,最右位置是他的初始位置加上他右边所有比他小的数的个数,因为这些数会先被换到他的左侧。所以只用统计每个数右边比他小的数的个数就行了,这里我用的是线段树的办法。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
/*-------------------------------------*/
#define max(a,b) (a>b)?a:b
#define min(a,b) (a>b)?b:a
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1

int idx[maxn];
int num[maxn];
int sum[maxn << 2];
void pushup(int rt){
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void update(int id,int l, int r, int rt){
if (l==r){
sum[rt] = 1;
return ;
}
int m = (l+r) >>1;
if (id <= m) {
update(id, lson);
}
if (m < id) {
update(id, rson);
}
pushup(rt);
}

int query(int L, int R, int l, int r, int rt){
if (L <= l && r <= R){
return sum[rt];
}
int m = (l + r) >> 1;
int ret = 0;
if (L <= m) {
ret += query(L , R , lson);
}
if (m < R) {
ret += quer
97bb
y(L , R , rson);
}
return ret;
}
/*----------------------------------*/
int main(){
int T,n,kas = 1;
cin >> T;
while(T --){
memset(sum, 0, sizeof(sum));
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &num[i]);
idx[num[i]] = i;
}
printf("Case #%d:", kas++);
for (int i = 1; i <= n; i++){
int l = min(idx[i], i);
int r = max(i, idx[i] + query(idx[i], n,1,n,1));
update(idx[i], 1, n, 1);
printf(" %d", r - l);
}
puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐