HDU 5775 Bubble Sort (線段樹亂搞)

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5775點擊打開鏈接

Bubble Sort

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2096    Accepted Submission(s): 1017


Problem Description
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
Hint
In first case, (3, 1, 2) -> (3, 1, 2) -> (1, 3, 2) -> (1, 2, 3) the leftmost place and rightmost place of 1 is 1 and 2, 2 is 2 and 3, 3 is 1 and 3 In second case, the array has already in increasing order. So the answer of every number is 0.


求上面那串代碼下排序每個數的左右距離差

這道題沒理解透就A了。。

說一下我的操作吧。

分別對序列進行下標排序下的值逆序操作和值排序下的下標逆序操作 

然後求兩個的最大值

試了兩組樣例發現結果一樣。。

交了發然後就A了。。

嘗試強行解釋一下吧 也是目前我的理解

因爲是求差 因此每個數在那段代碼的冒泡排序下會有兩種情況

一種是與後面比他小的值交換 

另一種是與比他前面大的值交換

所以最後就是要麼左移要麼右移  次數取最大

如果有大佬能解釋下小弟感激不盡。。

#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
struct xjy
{
    int left;
    int right;
    int num;
}tree[maxn<<2];
struct xxjy
{
    int num;
    int index;
};
struct xjyy
{
    int ans1;
    int ans2;
    int index;
    bool operator < (const xjyy &r)const
    {
        return index<r.index;
    }
};
int cmp1(xxjy a,xxjy b)
{
    return a.num<b.num;
}
int cmp2(xxjy a,xxjy b)
{
    return a.index<b.index;
}
xxjy a[maxn];
xjyy anss[maxn];
int ans;
int n;
void build(int root,int left,int right)
{
    tree[root].left=left;
    tree[root].right=right;
    tree[root].num=0;
    if(left==right)
        return;
    int mid=(left+right)>>1;
    build(root<<1,left,mid);
    build(root<<1|1,mid+1,right);
}
void update(int root,int left,int right)
{
    if(tree[root].left==left&&tree[root].right==right)
    {
        tree[root].num++;
        return;
    }
    int mid=(tree[root].left+tree[root].right)>>1;
    if(right<=mid)
        update(root<<1,left,right);
    else if(left>mid)
        update(root<<1|1,left,right);
    else
    {
        update(root<<1,left,mid);
        update(root<<1|1,mid+1,right);
    }
    tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
}
void query(int root,int left,int right)
{
    if(tree[root].left==left&&tree[root].right==right)
    {
        ans+=tree[root].num;
        return;
    }
    int mid=(tree[root].left+tree[root].right)>>1;
    if(right<=mid)
        query(root<<1,left,right);
    else if(left>mid)
        query(root<<1|1,left,right);
    else
    {
        query(root<<1,left,mid);
        query(root<<1|1,mid+1,right);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cnt=1;cnt<=t;cnt++)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int mid;
            scanf("%d",&mid);
            a[i].num=mid;
            a[i].index=i;
            anss[i].index=mid;
        }
        build(1,1,n);
        sort(a+1,a+1+n,cmp2);
        for(int i=1;i<=n;i++)
        {
            ans=0;
            query(1,a[i].num,n);
            //cout << ans << endl;
            anss[i].ans2=ans;
            update(1,a[i].num,a[i].num);
        }
        sort(a+1,a+1+n,cmp1);
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            ans=0;
            query(1,a[i].index,n);
            //cout << ans <<endl;
            anss[a[i].index].ans1=ans;
            update(1,a[i].index,a[i].index);
        }
        sort(anss+1,anss+1+n);
        printf("Case #%d:",cnt);
        for(int i=1;i<=n;i++)
        {
            printf("\n%d %d\n",anss[i].ans1,anss[i].ans2);
            printf(" %d",max(anss[i].ans1,anss[i].ans2));
        }
        printf("\n");
    }
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章