Problem Description
Matt’s friend K.Bro is an ACMer.
Yesterday, K.Bro learnt an algorithm: Bubble sort. Bubble sort will compare each pair of adjacent items and swap them if they are in the wrong order. The process repeats until no swap is needed.
Today, K.Bro comes up with a new algorithm and names it K.Bro Sorting.
There are many rounds in K.Bro Sorting. For each round, K.Bro chooses a number, and keeps swapping it with its next number while the next number is less than it. For example, if the sequence is “1 4 3 2 5”, and K.Bro chooses “4”, he will get “1 3 2 4 5” after this round. K.Bro Sorting is similar to Bubble sort, but it’s a randomized algorithm because K.Bro will choose a random number at the beginning of each round. K.Bro wants to know that, for a given sequence, how many rounds are needed to sort this sequence in the best situation. In other words, you should answer the minimal number of rounds needed to sort the sequence into ascending order. To simplify the problem, K.Bro promises that the sequence is a permutation of 1, 2, . . . , N .
Yesterday, K.Bro learnt an algorithm: Bubble sort. Bubble sort will compare each pair of adjacent items and swap them if they are in the wrong order. The process repeats until no swap is needed.
Today, K.Bro comes up with a new algorithm and names it K.Bro Sorting.
There are many rounds in K.Bro Sorting. For each round, K.Bro chooses a number, and keeps swapping it with its next number while the next number is less than it. For example, if the sequence is “1 4 3 2 5”, and K.Bro chooses “4”, he will get “1 3 2 4 5” after this round. K.Bro Sorting is similar to Bubble sort, but it’s a randomized algorithm because K.Bro will choose a random number at the beginning of each round. K.Bro wants to know that, for a given sequence, how many rounds are needed to sort this sequence in the best situation. In other words, you should answer the minimal number of rounds needed to sort the sequence into ascending order. To simplify the problem, K.Bro promises that the sequence is a permutation of 1, 2, . . . , N .
Input
The first line contains only one integer T (T ≤ 200), which indicates the number of test cases. For each test case, the first line contains an integer N (1 ≤ N ≤ 10 6).
The second line contains N integers a i (1 ≤ a i ≤ N ), denoting the sequence K.Bro gives you.
The sum of N in all test cases would not exceed 3 × 10 6.
The second line contains N integers a i (1 ≤ a i ≤ N ), denoting the sequence K.Bro gives you.
The sum of N in all test cases would not exceed 3 × 10 6.
Output
For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1), y is the minimal number of rounds needed to sort the sequence.
Sample Input
2 5 5 4 3 2 1 5 5 1 2 3 4
Sample Output
Case #1: 4 Case #2: 1
Hint
In the second sample, we choose “5” so that after the first round, sequence becomes “1 2 3 4 5”, and the algorithm completes. Source
区域赛居然还会出这么水的题==
说题意:正常的逆序数做法是从头到尾遍历一遍,累加在此数之前出现的比这个数值大的数的个数,可能还要用到离散化,比方说这个题:(本题没必要离散化 都是1-n之间的数)
poj2299Ultra-QuickSort【线段树求逆序数】离散化
然而本题是要求在数组里面选定一个数,一直向后与比他小的数交换,直到下一个数字比他大停止。找到这么一个数叫做一个round,问最少需要几个round?很明显一定要套逆序数的模板,只是在最后for循环里面改动一下。我们考虑如果在一个数num[i]后存在比他小的num[j],那么这个数一定要被扔到后面,为什么,我们不是只是交换相邻的两个数字吗,要是在他后面比他小但是不相邻呢?考虑这样的一组示例:4,5,6,3,2,1对于4来说 123虽然不和他挨着,但是5,6终究要传到后面去,这时候4还是要交换的对吧。具体实现呢:我们之前求逆序数的方法是累加在某个数之前出现比他大的数,而这个题显然要反过来求,我们就反向遍历,若存在先出现的比这个数小的情况,sum++即可,注意,求和的时候遇到大于0就return!否则超时
/************
hdu5122
2016.3.21
1856MS 38092K 1928 B C++
*************/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000005
struct node
{
int id,val;
}num[maxn];
bool cmp(node n1,node n2)
{
return n1.val<n2.val;
}
struct Tree
{
int l,r,tot;
}tree[maxn<<2];
int rnk[maxn];
void build(int rt,int l,int r)
{
tree[rt].l=l;tree[rt].r=r;
tree[rt].tot=0;
if(l==r)return;
int mid=(l+r)/2;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}
void update(int rt,int x)
{
tree[rt].tot++;
if(tree[rt].l==tree[rt].r&&tree[rt].l==x)
return;
int mid=(tree[rt].l+tree[rt].r)/2;
if(x<=mid)update(rt<<1,x);
else update(rt<<1|1,x);
}
int query(int rt,int l,int r)
{
int sum=0;
if(tree[rt].l==l&&tree[rt].r==r)
return tree[rt].tot;
int mid=(tree[rt].l+tree[rt].r)/2;
if(r<=mid)
{
sum=query(rt<<1,l,r);
if(sum>0)return 1;
}
else if(l>mid)
{
sum=query(rt<<1|1,l,r);
if(sum>0)return 1;
}
else
{
sum=query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r);
if(sum>0)return 1;
}
return sum;
}
int change[maxn];
int main()
{
、、 freopen("cin.txt","r",stdin);
int t,n,cas=1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&num[i].val);
num[i].id=i;
change[num[i].val]=i;
}
//sort(num,num+n,cmp);
//for(int i=0;i<n;i++) rnk[num[i].id]=i+1;
build(1,0,n+1);
int sum=0,tmp=0;
for(int i=n-1;i>=0;i--)
{
// int x = rnk[i];
tmp=query(1,0,num[i].val-1);
// printf("i=%d,sum=%d\n",i,sum);
if(tmp>0) sum++;
update(1,num[i].val);
}
printf("Case #%d: %d\n",cas++,sum);
}
return 0;
}