POJ 2299 Ultra-QuickSort

来源:互联网 发布:恋爱 知乎 编辑:程序博客网 时间:2024/06/16 19:13

求逆序对个数。

暴力 n^2 TLE妥妥的。要么 归并排序的时候统计,要么线段树或者数状数组优化。

时间复杂度都是 n*logn


线段树求逆序数怎么写呢。

例如样例的

9 1 0 5 4

其位置pos 为

0 1 2 3 4


再来一个数组设为

0 0 0 0 0

线段树先插入 (9,0),把插入的位置 0 变成 1。

1 0 0 0 0

然后统计 left=0,right=(0-1) 由于right比left 小,不进行查询。


再插入(5,3) ,把插入的位置 0 变成 1。

1 0 0 1 0

然后统计 left=0,right=(3-1) 对线段树进行查询,查询 0~2 的和。


再插入 (4,4)………

再插入 (1,1)………

再插入 (0,2)………


这样就分别求出 这些数左边比他们大的数。加起来就是这个数列逆序数的总数。


线段树的 插入和查询 都是 logn的时间复杂度。总共n次。为n*logn。


不过注意的是 题意中说了最后答案很大,所以统计的时候需要用long long 加起来。

PS:我就WA了一发。


#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<bitset>#include<vector>#include<cmath>#define INF 0x7fffffff#define eps 1e-8#define LL long long#define PI 3.141592654#define CLR(a,b) memset(a,b,sizeof(a))#define FOR(i,a,b) for(int i=a;i<b;i++)#define FOR_(i,a,b) for(int i=a;i>=b;i--)#define pub push_back#define puf push_front#define pob pop_back#define pof pop_front#define mp make_pair#define ft first#define sd second#define sf scanf#define pf printf#define sz(v) ((int)(v).size())#define all(v) (v).begin(),(v).end()#define acfun std::ios::sync_with_stdio(false)#define SIZE 3000000  +1#define MOD 1000000007using namespace std;struct lx{    int a,p;    bool friend operator < (lx a,lx b)    {        return a.a>b.a;    }};lx l[SIZE];int n;int t[SIZE];int site;void update(int o,int l,int r){    if(l==r)t[o]=1;    else    {        int m=(l+r)>>1;        if(site<=m)update(o*2,l,m);        else update(o*2+1,m+1,r);        t[o]=t[o*2]+t[o*2+1];    }}int ql,qr;int query(int o,int l,int r){    if(l>=ql&&r<=qr)return t[o];    int m=(l+r)>>1;    int ans=0;    if(ql<=m)ans+=query(o*2,l,m);    if(qr>m)ans+=query(o*2+1,m+1,r);    return ans;}int main(){    while(sf("%d",&n),n)    {        FOR(i,1,n+1)        {            sf("%d",&l[i].a);            l[i].p=i;        }        sort(l+1,l+n+1);        CLR(t,0);        LL ans=0;        //fuck long long        FOR(i,1,n+1)        {            site=l[i].p;            update(1,1,n);            ql=1,qr=site-1;            if(ql<=qr)            ans+=query(1,1,n);            //pf("%lld==\n",ans);        }        pf("%lld\n",ans);    }}


0 0
原创粉丝点击