<span>HDU5775 Bubble Sort(树状数组求逆序数)</span>

题意:

给你一段序列(排列)和排序方式

让你求出每个数在排序过程中移动的范围

思路:

序列排序结束是升序的,能移动到的最左端就是min(i,a[i])

如果a[i]比较大,他就不会向左移,就是a[i],如果比较小就最多移动到i的位置

能移动到的最右端就是当前的i加上从右向左比他小的数的个数

因为这些数要优先移动到他的左端,

这个个数可以用树状数组求

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=1e5+10;
int a[N],c[N],l[N],r[N],n;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int num)
{
    while(x<=n)
    {
        c[x]+=num;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int s=0;
    while(x>0)
    {
        s+=c[x];
        x-=lowbit(x);
    }
    return s;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        printf("Case #%d:",++cas);
        scanf("%d",&n);
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=n;i>=1;i--)
        {
            l[a[i]]=min(a[i],i);
            r[a[i]]=i+getsum(a[i]);
            update(a[i],1);
        }
        for(int i=1;i<=n;i++) printf(" %d",r[i]-l[i]);
        printf("\n");
    }
    return 0;
}

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
2024-12-30 18:02
程序员牛肉:1.可以标记一下自己的学校是985,有一些hr可能没想到你这个院校是985的。 2.简历所呈现出来的能力还是有点差的,苍穹外卖+黑马点评。这在java技术域里面也就是刚学三四个月的样子,大厂现在招人少,小厂又更加希望你能直接过来干活。就你简历上呈现出来的能力,确实是有点难找,肉眼可见的不懂技术。 第一个项目中:简单的使用redis也算是亮点嘛?使用jwt,threadlocal也算是亮点?你不就是调了几个包嘛?Nginx作为服务器也能写出来,这不是前端的活嘛? 第二个项目中:分布式锁+mq消息队列+Lua队列。真没啥好问的。属于面试官看一眼就阳痿的简历,没有任何想提问的欲望。 我给你建议是好好的挖一挖这个项目吧,其实苍穹外卖和黑马点评这两个项目很不错了,只不过是太烂大街了导致面试官没啥问的兴趣,所以不太推荐写简历上。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务