zoukankan      html  css  js  c++  java
  • wikioi1688 求逆序对

    给定一个序列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 long
    using 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
    ",ans);
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    一个面试问题的答案总结
    全局变量与局部变量的特点
    浮点数类型在内存当中是如何存储的
    常用的几种调用约定
    裸函数
    安卓活动的启动模式
    安卓的生命周期
    android中的内部存储与外部存储
    堆栈图学习汇编结束篇最后一个堆栈图的练习
    Android内部存储与外部存储的文件操作类
  • 原文地址:https://www.cnblogs.com/zhber/p/4036005.html
Copyright © 2011-2022 走看看