题目
Description
你收到一项对数组进行排序的任务,数组中是1到N个一个排列。你突然想出以下一种特别的排序方法,分为以下N个阶段:
•阶段1,把数字1通过每次交换相邻两个数移到位置1;
•阶段2,用同样的方法把N移到位置N;
•阶段3,把数字2移到位置2处;
•阶段4,把数字N-1移到位置N-1处;
•依此类推。
换句话说,如果当前阶段为奇数,则把最小的未操作的数移到正确位置上,如果阶段为偶数,则把最大的未操作的数移到正确位置上。
写一个程序,给出初始的排列情况,计算每一阶段交换的次数。
•阶段1,把数字1通过每次交换相邻两个数移到位置1;
•阶段2,用同样的方法把N移到位置N;
•阶段3,把数字2移到位置2处;
•阶段4,把数字N-1移到位置N-1处;
•依此类推。
换句话说,如果当前阶段为奇数,则把最小的未操作的数移到正确位置上,如果阶段为偶数,则把最大的未操作的数移到正确位置上。
写一个程序,给出初始的排列情况,计算每一阶段交换的次数。
Input
第一行包含一个整数N(1<=N<=100000),表示数组中元素的个数。
接下来N行每行一个整数描述初始的排列情况。
接下来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
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 }