wikioi1688 求逆序对

来源:互联网 发布:手机扫描照片软件 编辑:程序博客网 时间:2024/05/01 23:10

给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目

 

数据范围:N<=105Ai<=105。时间限制为1s。


第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。

所有逆序对总数.

4

3

2

3

2

3

感觉我又刷起水题了……

用归并排序线段树树状数组的都太low了

看我用treap搞之

每次询问比它大的有多少个,然后插入就好了

#include<cstdio>#include<cstdlib>#include<ctime>#define LL long longusing namespace std;struct SBT{int l,r,dat,rnd,rep,son;}tree[200010];int n,treesize,root;LL ans;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}inline void update(int k){tree[k].son=tree[k].rep+tree[tree[k].l].son+tree[tree[k].r].son;}inline void right_rotate(int &k){int t=tree[k].l;tree[k].l=tree[t].r;tree[t].r=k;tree[t].son=tree[k].son;update(k);k=t;}inline void left_rotate(int &k){int t=tree[k].r;tree[k].r=tree[t].l;tree[t].l=k;tree[t].son=tree[k].son;update(k);k=t;}inline void insert(int &k,int x){if(!k){k=++treesize;tree[k].dat=x;tree[k].rep=1;tree[k].son=1;return;}tree[k].son++;if (tree[k].dat==x){tree[k].rep++;return;}if(x<tree[k].dat){insert(tree[k].l,x);if(tree[tree[k].l].rnd>tree[k].rnd)right_rotate(k);}else{insert(tree[k].r,x);if(tree[tree[k].r].rnd>tree[k].rnd)left_rotate(k);}}inline int query(int k,int x){if (!k)return 0;if (tree[k].dat>x)return tree[k].rep+tree[tree[k].r].son+query(tree[k].l,x);if (tree[k].dat==x)return query(tree[k].r,x);if (tree[k].dat<x)return query(tree[k].r,x);}int main(){n=read();for (int i=1;i<=n;i++){int x=read();ans+=query(root,x);insert(root,x);}printf("%lld\n",ans);}

0 0
原创粉丝点击