POJ 2188线段树求逆序对

题目给的输入是大坑,算法倒是很简单……

输入的是绳子的编号wire ID,而不是上(或下)挂钩对应下(或上)挂钩的编号。 所以要转换编号,转换成挂钩的顺序,然后再求逆序数。

知道了这个以后直接乱搞就可以0msAC

(这题可以用冒泡排序过的……) (n<=1000)

// by SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,tree[6666],ans=0;
struct Node
{
    int x,y;
}point[1005],node[1005];
bool cmp(Node a,Node b)
{
    return a.x<b.x;
}
int query(int l,int r,int pos,int W)
{
    if(l>=W)return tree[pos];
    int mid=(l+r)>>1;
    if(mid<W)return query(mid+1,r,pos<<1|1,W);
    else return query(l,mid,pos<<1,W)+query(mid+1,r,pos<<1|1,W);
}
void insert(int l,int r,int pos,int W)
{
    if(l==r){tree[pos]++;return;}
    int mid=(l+r)>>1;
    if(mid>=W)insert(l,mid,pos<<1,W);
    else insert(mid+1,r,pos<<1|1,W);
    tree[pos]=tree[pos<<1]+tree[pos<<1|1];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&point[i].x,&point[i].y);
    }
    for(int i=1;i<=n;i++)
    {
        node[point[i].x].x=i;
        node[point[i].y].y=i;
    }
    sort(node+1,node+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        ans+=query(1,n,1,node[i].y);
        insert(1,n,1,node[i].y);
    }
    printf("%d\n",ans);
}

这里写图片描述

posted @ 2016-08-26 19:34  SiriusRen  阅读(165)  评论(0)    收藏  举报