P is a permutation of the integers from 1 to N(index starting from 1).
Here is the code of Bubble Sort in C++.
for(int i=1;i<=N;++i)
for(int j=N,t;j>i;—j)
if(P[j-1] > P[j])
t=P[j],P[j]=P[j-1],P[j-1]=t;
After the sort, the array is in increasing order. ?? wants to know the absolute values of difference of rightmost place and leftmost place for every number it reached.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each consists of one line with one integer N, followed by another line with a permutation of the integers from 1 to N, inclusive.
limits
T <= 20
1 <= N <= 100000
N is larger than 10000 in only one case.
Output
For each test case output “Case #x: y1 y2 … yN” (without quotes), where x is the test case number (starting from 1), and yi is the difference of rightmost place and leftmost place of number i.
Sample Input
2
3
3 1 2
3
1 2 3
Sample Output
Case #1: 1 1 2
Case #2: 0 0 0
[分析]
先要看题目所给的冒泡,他的思路是小的往左边移动。
有的数字所在的位置比本该在的位置大,所以他要往左边主动移动。
有的数字所在的位置比本该在的位置小,因为冒泡是移动小的,所以这些数字都不是主动移动的,他们是因为其他的数字移动了,所以被动往右移动。
知道了这些你就可以分析出,左位置只能是min(a[i], i);,(因为被动移动只会向右边移动)
右位置必然是当前位置加上你右边有多少比你小的数i + (a[i] - 1 - sum(a[i]));
右边有多少比你小的数通过树状数组计算,非常方便
[代码]
#include <cstdio>
#include <cstring>
#include<algorithm>
using namespace std;
#define maxn 100005
int c[maxn];
int a[maxn];
struct ANS
{
int l, r;
}ans[maxn];
int Lowbit(int x) // 2^k
{
return x&(-x);
}
void update(int i, int x)//i点增量为x
{
while (i <= maxn)
{
c[i] += x;
i += Lowbit(i);
}
}
int sum(int x)//区间求和 [1,x]
{
int sum = 0;
while (x>0)
{
sum += c[x];
x -= Lowbit(x);
}
return sum;
}
int Getsum(int x1, int x2) //求任意区间和
{
return sum(x2) - sum(x1 - 1);
}
int main()
{
int t,kase=0;
scanf("%d", &t);
while (t--)
{
memset(c, 0, sizeof(c));
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
//i - sum(a[i]);
ans[a[i]].l = min(a[i], i);
ans[a[i]].r = i + (a[i] - 1 - sum(a[i]));
update(a[i], 1);
}
printf("Case #%d:", ++kase);
for (int i = 1; i <= n; i++)
{
printf(" %d", abs(ans[i].l - ans[i].r));
}
printf("\n");
}
}