某看起来不会做题1

P2448 无尽的生命

题目描述

逝者如斯夫,不舍昼夜!
叶良辰认为,他的寿命是无限长的,而且每天都会进步。
叶良辰的生命的第一天,他有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)




看来是随机出一道好题
肯定不能用逆序对直接搞
那样做只能得70分?

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lowbit((a)) (a)&(-(a))
using namespace std;

typedef long long ll;

int hash[N],b[N],a[N];
ll ans,tree[N];
int n,m,cnt;

struct node{
    int x,y;
}q[N];

inline int read(){
    int a=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(a=0;isdigit(c);a=a*10+c-'0',c=getchar());
    return a*f;
}

inline int find(int x) {
    int l=1,r=m;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(hash[mid]==x) return mid;
        else if(hash[mid]<x) l=mid+1; 
        else r=mid-1;
    }
    return r;
}
struct BIT{
    int n;
    int tre[N];
    init(int n){
        this-n=n;
        memset(tre,false,sizeof(tre));
    }


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

inline void add(int x,ll val) {
    for (int i=x;i<=m;i+=lowbit(i)) tree[i]+=val;
}

inline ll query(int x) {
    ll sum=0;
    for (int i=x;i;i-=lowbit(i)) sum+=tree[i];
    return sum;
}

int main() {
    n=read();
    for (int i=1;i<=n;i++) a[++cnt]=q[i].x=read(),a[++cnt]=q[i].y=read();
    sort(a+1,a+cnt+1); 
    for (int i=1;i<=cnt;i++)
        if (a[i]!=a[i-1]) hash[++m]=a[i];
    for (int i=1;i<=m;i++) b[i]=i;
    for (int i=1;i<=n;i++) {
        int x=find(q[i].x),y=find(q[i].y);
        swap(b[x],b[y]);
    }
    add(b[m],1);
    for (int i=m-1;i;i--) {
        ll x=(ll)(hash[i+1]-hash[i]-1),p=query(i);
        ans=ans+(x*p);
        add(i,x);
        ans=ans+query(b[i]-1);
        add(b[i],1);
    }
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/qdscwyy/p/7860443.html