zoukankan      html  css  js  c++  java
  • JZOJ 1386. 排序

    题目

    Description

      你收到一项对数组进行排序的任务,数组中是1到N个一个排列。你突然想出以下一种特别的排序方法,分为以下N个阶段:
      •阶段1,把数字1通过每次交换相邻两个数移到位置1;
      •阶段2,用同样的方法把N移到位置N;
      •阶段3,把数字2移到位置2处;
      •阶段4,把数字N-1移到位置N-1处;
      •依此类推。
      换句话说,如果当前阶段为奇数,则把最小的未操作的数移到正确位置上,如果阶段为偶数,则把最大的未操作的数移到正确位置上。
      写一个程序,给出初始的排列情况,计算每一阶段交换的次数。
     

    Input

      第一行包含一个整数N(1<=N<=100000),表示数组中元素的个数。
      接下来N行每行一个整数描述初始的排列情况。

    Output

      输出每一阶段的交换次数。
     

    Sample Input

    输入1:
    3
    2
    1
    3
    
    
    输入2:
    5
    5
    4
    3
    2
    1
    
    输出3:
    7
    5
    4
    3
    7
    1
    2
    6
    

    Sample Output

    输出1:
    1
    0
    0
    
    输出2:
    4
    3
    2
    1
    0
    
    输出3:
    4
    2
    3
    0
    2
    1
    0
    
     

    Data Constraint

     
     

    Hint

    【数据范围】
      70%的数据N<=100

    分析

     

    • 刚开始是想用差分数值纪录移动的差值
    • 但是这不能直接一个区间直接加
    • 因为影响向右的数就要减或加所以要n
    • 我们认真思考,答案其实不就是前面或后面还未移动的个数
    • 向前移动的就数前面的,不然数后面
    • 线段树区间查询,单点修改

    代码

     1 #include<iostream>
     2 using namespace std;
     3 int a[100001],to[100001],bj[100001];
     4 struct sb
     5 {
     6     int l,r,w;
     7 }t[100001*4];
     8 void build(int k,int a,int b)
     9 {
    10     t[k].l=a; t[k].r=b;
    11     if (a==b) {
    12         t[k].w=1;
    13         return;
    14     }
    15     int mid=a+b>>1;
    16     build(k<<1,a,mid);
    17     build(k<<1|1,mid+1,b);
    18     t[k].w=t[k<<1].w+t[k<<1|1].w;
    19 }
    20 int check(int x,int y,int k)
    21 {
    22     if (t[k].l==x&&t[k].r==y)
    23         return t[k].w;
    24     int mid=(t[k].l+t[k].r)/2;
    25     if (y<=mid) return check(x,y,k*2);
    26     else if (x>mid) return check(x,y,k*2+1);
    27     else
    28         return check(x,mid,k*2)+check(mid+1,y,k*2+1);
    29 }
    30 void change(int k,int mb)
    31 {
    32     if (t[k].l<=mb&&t[k].r>=mb)
    33         t[k].w--;
    34     if (t[k].l==t[k].r) return;
    35     int mid=t[k].l+t[k].r>>1;
    36     if (mb<=mid) change(k<<1,mb);
    37     else change(k<<1|1,mb);
    38 }
    39 int main ()
    40 {
    41     int n;
    42     cin>>n;
    43     for (int i=1;i<=n;i++) cin>>a[i],to[a[i]]=i;
    44     build(1,1,n);
    45     int tot=0,i=1,j=n;
    46     while (++tot<=n)
    47     {
    48         if (tot%2==1)
    49         {
    50             int wz=to[i],ans=check(1,wz,1)-1;
    51             if (ans<0) ans=0;
    52             cout<<ans<<endl;
    53             change(1,wz);
    54             i++;
    55         }
    56         else
    57         {
    58             int wz=to[j],ans=check(wz,n,1)-1;
    59             if (ans<0) ans=0;
    60             cout<<ans<<endl;
    61             change(1,wz);
    62             j--;
    63         }
    64     }
    65 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    疫情环境下的网络学习笔记 python 5.8 数据库入门终章
    疫情环境下的网络学习笔记 python 5.7 navicat数据库,例题,sql注入
    疫情环境下的网络学习笔记 python 5.6 暂时看看
    疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键
    疫情环境下的网络学习笔记 python 5.4 数据库基础
    疫情环境下的网络学习笔记 python 4.30 初识数据库
    疫情环境下的网络学习笔记 python 4.29 网络小项目
    XJOI 夏令营501-511测试11 游戏
    XJOI 夏令营501-511测试11 统计方案
    CF1197D Yet Another Subarray Problem
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11318872.html
Copyright © 2011-2022 走看看