洛谷2448 无尽的生命

来源:互联网 发布:甲骨文java认证 编辑:程序博客网 时间:2024/06/09 15:46

题目:http://www.luogu.org/problem/show?pid=2448
分析:首先离散化,然后树状数组求所有操作过的数产生的逆序对,再求每个操作过的数与没操作过的数产生的逆序对,因为原始序列有序,所以很方便。
代码:

#include <cstdio>#include <iostream>#include <algorithm>#include <map>using namespace std;const int Tmax=200005;struct node{    int x,p,lisan;};node G[Tmax]; int k,last,C1[Tmax],C2[Tmax];long long int ans;map<int,int> F,fx;bool cmp(node lhs,node rhs){    return lhs.x<rhs.x;}bool cmp2(node lhs,node rhs){    return lhs.p<rhs.p;}void init(){    int i;    sort(G+1,G+1+last,cmp);    for(i=1;i<=last;i++)    {        G[i].lisan=i;        fx[G[i].x]=i;    }    sort(G+1,G+1+last,cmp2);    return;}int lowbit(int x){    return x&-x;}int sum(int x){    int sum=0;    for(;x>0;x-=lowbit(x))        sum+=C1[x];    return sum;}void add(int x){    for(;x<=Tmax-1;x+=lowbit(x))        C1[x]++;    return;}void work(){    int i,num;    for(i=1;i<=last;i++)    {        num=sum(Tmax-1)-sum(G[i].lisan);        add(G[i].lisan);        ans+=num;        if(G[i].p>G[i].x)        {            num=fx[G[i].p]-fx[G[i].x]-1;            ans+=max(0,G[i].p-G[i].x-1-num);        }        else {            num=fx[G[i].x]-fx[G[i].p]-1;            ans+=max(0,G[i].x-G[i].p-1-num);        }    }    cout<<ans;    return;}int main(){    int i,a,b,pa,pb;    scanf("%d",&k);    for(i=1;i<=k;i++)    {        scanf("%d%d",&a,&b);        if(!F.count(a)){            pa=++last;            G[pa].x=G[pa].p=a;            F[a]=pa;        }        else pa=F[a];        if(!F.count(b)){            pb=++last;            G[pb].x=G[pb].p=b;            F[b]=pb;        }        else pb=F[b];        swap(G[pa].x,G[pb].x);    }    init();    work();    return 0;}
0 0
原创粉丝点击