Codeforces-540E.Infinite Inversions区间化点求交换逆序对(离散化+树状数组)

E. Infinite Inversions

time limit per test            memory limit per test

2 seconds                       256 megabytes

There is an infinite sequence consisting of all positive integers in the increasing order: p = {1, 2, 3, ...}. We performed n swap operations with this sequence. A swap(a, b) is an operation of swapping the elements of the sequence on positions aand b. Your task is to find the number of inversions in the resulting sequence, i.e. the number of such index pairs (i, j), that i < j and pi > pj.

Input

The first line contains a single integer n (1 ≤ n ≤ 105) — the number of swapoperations applied to the sequence.

Each of the next n lines contains two integers ai and bi (1 ≤ ai, bi ≤ 109, ai ≠ bi) — the arguments of the swap operation.

Output

Print a single integer — the number of inversions in the resulting sequence.

Examples

Input

2
4 2
1 4

Output

4

Input

3
1 6
3 4
2 5

Output

15

Note

In the first sample the sequence is being modified as follows:  . It has 4 inversions formed by index pairs (1, 4), (2, 3), (2, 4) and (3, 4).


题目大意:给你一个1到n的序列,然后给你m次位置的交换,问你最终有几对逆序对。。。。刚开始还以为要把每次交换的逆序对数都回答出来。。。那么就变成了动态逆序对的位置交换了我之前的这篇博客就有分块处理的动态逆序对,但它的n太大了。。。。所以就不会了QAQ。。。。实际上仔细看题目就会知道,他只要求最后求一次逆序对就好了,那么也就是说我们可以开心地将它离散化,区间化点(就是将一个区间转化成一个点,然后这个点保留着这个区间的区间长度)就可以直接一边插入数一边求逆序对了(这里的数据较小map离散化就可以过了。。。之前的一题就不行这是更恶心的离散化+线段树Codeforces-915E,也安利一波我的博客qwq)

以下是AC代码:

#include 
using namespace std;

#define ll long long

const int mac=1e5+10;

struct node
{
    int l,r;
}a[mac];
int b[mac<<2],c[mac<<2],tree[mac<<2],tot=0;
int len[mac<<2];

unordered_mapq;

void in(int &x)
{
    int f=0;
    char ch=getchar();
    while (ch>'9' || ch<'0') ch=getchar();
    while (ch>='0' && ch<='9') f=(f<<3)+(f<<1)+ch-'0',ch=getchar();
    x=f;
}

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

void update(int pos,int val)
{
    while (pos<=tot){
        tree[pos]+=val;
        pos+=lowbit(pos);
    }
}

int query(int pos)
{
    int sum=0;
    while (pos){
        sum+=tree[pos];
        pos-=lowbit(pos);
    }
    return sum;
}

int main()
{
    int n,cnt=0;
    scanf ("%d",&n);
    for (int i=1; i<=n; i++){
        int l,r;
        in(l);in(r);
        a[i].l=l;a[i].r=r;
        b[++cnt]=l;b[++cnt]=r;
    }
    sort(b+1,b+1+cnt);
    int p=b[1];
    c[1]=1;tot=1;q[b[1]]=1;len[1]=1;
    for (int i=2; i<=cnt; i++){
        if (b[i]!=p) {
            if (b[i]!=b[i-1]+1) c[++tot]=tot,len[tot]=b[i]-b[i-1]-1;
            p=b[i];
            q[b[i]]=++tot;
            c[tot]=tot;
            len[tot]=1;
        }
    }
    for (int i=1; i<=n; i++) swap(c[q[a[i].l]],c[q[a[i].r]]);
    ll ans=0,qsum=0;
    for (int i=1; i<=tot; i++){
        ans+=(qsum-query(c[i]-1))*len[i];
        qsum+=len[i];
        update(c[i],len[i]);
    }
    printf ("%lld\n",ans);
}

 

你可能感兴趣的:(#,线段树&树状数组,Codeforces)