洛谷 2448 无尽的生命

https://www.luogu.org/problem/show?pid=2448

题目描述

逝者如斯夫,不舍昼夜!

叶良辰认为,他的寿命是无限长的,而且每天都会进步。

叶良辰的生命的第一天,他有1点能力值。第二天,有2点。第n天,就有n点。也就是S[i]=i

但是调皮的小A使用时光机,告诉他第x天和第y天,就可以任意交换某两天的能力值。即S[x]<-->S[y]

小A玩啊玩,终于玩腻了。

叶良辰:小A你给我等着,我有100种办法让你生不如死。除非能在1秒钟之内告知有多少对“异常对”。也就是说,最后的能力值序列,有多少对的两天x,y,其中x<y,但是能力值S[x]>S[y]?

小A:我好怕怕啊。

于是找到了你。

输入输出格式

输入格式:

第一行一个整数k,表示小A玩了多少次时光机

接下来k行,x_i,y_i,表示将S[x_i]与S[y_i]进行交换

输出格式:

有多少“异常对”

输入输出样例

输入样例#1:
2
4 2
1 4
输出样例#1:
4

说明

样例说明

最开始是1 2 3 4 5 6...

然后是 1 4 3 2 5 6...

然后是 2 4 3 1 5 6...

符合的对是[1 4] [2 3] [2 4] [3 4]

对于30%的数据,x_i,y_i <= 2000

对于70%的数据, x_i,y_i <= 100000

对于100%的数据, x_i.y_i <= 2^31-1 k<=100000

 

将连续的没有交换的压缩成一个点

树状数组求逆序对

#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int hashh[N<<1];
struct data
{
    int turn,x,y;
}g[N];
int dy2[N<<1];
struct node
{
    int len,id;
}e[N<<1];
int cnt,c[N<<1];
void add(int x,int y)
{
    while(x<=cnt)
    {
        c[x]+=y;
        x+=x&-x;
    }
}
int query(int x)
{
    int sum=0;
    while(x)
    {
        sum+=c[x];
        x-=x&-x;
    }
    return sum;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
    {
        scanf("%d%d",&g[i].x,&g[i].y);
        hashh[i*2-1]=g[i].x;
        hashh[i*2]=g[i].y;
        g[i].turn=i;
    }
    sort(hashh+1,hashh+n*2+1);
    int tot=unique(hashh+1,hashh+n*2+1)-(hashh+1);
    hashh[tot+1]=hashh[tot]+1;
    for(int i=1;i<=tot;i++)
    {
        if(hashh[i]+1==hashh[i+1]) 
        {
            e[++cnt].id=cnt;
            e[cnt].len=hashh[i+1]-hashh[i];
            dy2[i]=cnt;
        }
        else
        {
            e[++cnt].id=cnt;
            e[cnt].len=1;
            dy2[i]=cnt;
            e[++cnt].id=cnt;
            e[cnt].len=hashh[i+1]-hashh[i]-1;
        }
    }
    int a,b;
    for(int i=1;i<=n;i++)
    {
        a=lower_bound(hashh+1,hashh+tot+1,g[i].x)-hashh;
        b=lower_bound(hashh+1,hashh+tot+1,g[i].y)-hashh;
        a=dy2[a]; b=dy2[b];
        swap(e[a],e[b]);
    }
    long long ans=0;
    for(int i=cnt;i;i--)
    {
        ans+=1ll*query(e[i].id)*e[i].len;
        add(e[i].id,e[i].len);
    }
    printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7397989.html