• Peter算法小课堂—归并排序


    位运算

    <<

    这个符号相当于将一个数二进制往左移动几位,如(100110)2<<1=(001100)2。相当于乘以2的k次方

    >>

    这个符号相当于将一个数二进制往右移动几位,如(100110)2<<1=(0100110)2。相当于除以2的k次方

    归并排序

    先看一个视频一分钟了解"归并排序"_哔哩哔哩_bilibili

    main函数

    1. int main(){
    2. cin>>n;
    3. for(int i=0;i>x[i];
    4. msort(0,n-1);
    5. for(int i=0;i
    6. return 0;
    7. }

     这个我相信大家不看就知道怎么写吧

    msort函数

    msort函数的意义是“对数组l号到r号排序”

    思考五分钟:代码该如何填呢

    1. void msort(int l,int r){
    2. if(l==r) return ;
    3. int mid=(l+r)>>1;
    4. msort(l,mid);
    5. msort(mid+1,r);
    6. *************************************************
    7. * *
    8. * 将左右已经排序的两个部分合并 *
    9. * *
    10. *************************************************
    11. }

    我们可以使用双游标,给出代码和注释

    1. void msort(int l,int r){
    2. if(l==r) return ;
    3. int mid=(l+r)>>1;
    4. msort(l,mid);
    5. msort(mid+1,r);
    6. int i=l,j=mid+1;//双游标
    7. for(int k=l;k<=r;k++){
    8. if(i>mid) y[k]=x[j++];//如果左部分用完,填上右部分当前数
    9. else if(j>r) y[k]=x[i++];//如果右部分用完,填上左部分当前数
    10. else if(x[i]<=x[j]) y[k]=x[i++];//如果左部分当前数小于右部分当前数,填上左部分当前数
    11. else y[k]=x[j++];//否则填上右部分当前数
    12. }
    13. }

    分析一下时间复杂度

    但是,我们发现这个算法空间复杂度不行啊,但是我们不用管他,因为这个算法是稳定排序

    逆序对问题

    树状数组

    1. #include
    2. using namespace std;
    3. int tree[500010],ranks[500010],n;
    4. long long ans;
    5. struct point
    6. {
    7. int num,val;
    8. }a[500010];
    9. inline bool cmp(point q,point w)
    10. {
    11. if(q.val==w.val)
    12. return q.num
    13. return q.val
    14. }
    15. inline void insert(int p,int d)
    16. {
    17. for(;p<=n;p+=p&-p)
    18. tree[p]+=d;
    19. }
    20. inline int query(int p)
    21. {
    22. int sum=0;
    23. for(;p;p-=p&-p)
    24. sum+=tree[p];
    25. return sum;
    26. }
    27. int main()
    28. {
    29. scanf("%d",&n);
    30. for(int i=1;i<=n;i++)
    31. scanf("%d",&a[i].val),a[i].num=i;
    32. sort(a+1,a+1+n,cmp);
    33. for(int i=1;i<=n;i++)
    34. ranks[a[i].num]=i;
    35. for(int i=1;i<=n;i++)
    36. {
    37. insert(ranks[i],1);
    38. ans+=i-query(ranks[i]);
    39. }
    40. printf("%lld",ans);
    41. return 0;
    42. }

    此处不细讲

    归并排序

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const ll N=10000009;
    5. int n,x[N],y[N];
    6. ll solve(ll l,ll r){
    7. if(l==r)return 0;
    8. ll mid=(l+r)>>1;
    9. ll ret=0;
    10. ret+=solve(l,mid);
    11. ret+=solve(mid+1,r);
    12. ll i=l,j=mid+1;
    13. for(ll k=l;k<=r;k++){
    14. if(i>mid)y[k]=x[j++];
    15. else if(j>r)y[k]=x[i++];
    16. else if(x[i]<=x[j])y[k]=x[i++];
    17. else {ret+=mid-i+1;y[k]=x[j++];}
    18. }
    19. for(ll k=l;k<=r;k++)x[k]=y[k];
    20. return ret;
    21. }
    22. int main(){
    23. int cnt=0;
    24. cin>>n;
    25. for(ll i=0;i>x[i];
    26. cout<<solve(0,n-1)<
    27. return 0;
    28. }

    希望这些对大家有用,三联必回

  • 相关阅读:
    借助调试工具理解BLE协议_1.蓝牙简介和BLE工作流程
    如何成为开源组件库NutUI的contributor:解决issue并提交PR
    【剑指offer系列最终篇-END】75. 树中两个结点的最低公共祖先
    MybatisPlus---从入门到深化
    Linux如何设计一个线程池
    MongoDB数据库新手入门
    Node学习笔记之Node简介
    C#设置Textbox控件不可编辑
    vue3定时器的清除
    nodejs--开发自己的项目——5——个人中心模块——获取用户信息——设置的url:/my/userinfo/get请求
  • 原文地址:https://blog.csdn.net/zhang040818/article/details/134078839