CF #301 E:Infinite Inversions(逆序数,树状数组)

A-Combination Lock  B-School Marks   C-Ice Cave   D-Bad Luck Island   E-Infinite Inversions

E:Infinite Inversions

题意就是有一个序列1,2,3,4。。。。。

现在有n次交换,每次都把ab交换求最终形成的序列的逆序数;

逆序数分为两部分。一部分是交换过位置的,另一部分是没有交换过的。

离散化后,利用树状数组求出交换过的位置的逆序数的个数。

第二部分:

看一个样例:

2

1 6

9 5

得到的序列为6 2 3 4 9 1 7 8 5

首先对于数值6,其下标为1。在区间[1, 6]中,共有6个数。减去该区间中有3个是交换过位置的,则6-3 = 3是数值6对于当前序列所构成的逆序数个数。

对于数值9,下标为5,则在区间[5,9],共有5个数。减去该区间有3个是换过位置的,则逆序数为2。

对于数值1,其下标为6,在区间[1,6]中,~~~~~也有3个逆序数。

……

问题变为求一个区间的中有几个是交换过位置的,其实只要知道其下标的排名。例如下标1的排名为1,下标5排名2,下标6排名3,下标9排名4。

区间[1,6],则是3-1+1 = 3;

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
#define N 2010005
#define INF 0x3f3f3f3f

struct node
{
    int x, y;
}b[N];
map<int, int>M;
int a[N], cnt, Tree[N], V[N];

int lowbit(int x)
{
    return x&(-x);
}

void Update(int pos, int num)
{
    while(pos<=cnt)
    {
        Tree[pos]+=num;
        pos+=lowbit(pos);
    }
}

int GetSum(int pos)
{
    int s=0;
    while(pos)
    {
        s+=Tree[pos];
        pos-=lowbit(pos);
    }
    return s;
}

int main()
{
    int n;
    while(scanf("%d", &n)!=EOF)
    {
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        memset(V, 0, sizeof(V));
        cnt=1;
        for(int i=0; i<n; i++)
        {
            scanf("%d %d", &b[i].x, &b[i].y);
            a[cnt++]=b[i].x, a[cnt++]=b[i].y;
        }
        sort(a+1, a+cnt);
        cnt = unique(a, a+cnt)-a-1;
        for(int i=1; i<=cnt; i++)
            M[a[i]]=i, V[i]=i;
        for(int i=0; i<n; i++)
        {
            int p=M[b[i].x];
            int q=M[b[i].y];
            swap(V[p], V[q]);
        }
        long long ans=0;
        memset(Tree, 0, sizeof(Tree));
        for(int i=1; i<=cnt; i++)
        {
            int x=V[i];
            ans+=(i-1-GetSum(x));
            Update(x, 1);
        }
        for(int i=1; i<=cnt; i++)
            ans+=abs(a[V[i]]-a[i]-V[i]+i);
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2015-11-19 21:58  西瓜不懂柠檬的酸  Views(415)  Comments(0Edit  收藏  举报
levels of contents