返回顶部

Ultra-QuickSort树状数组

Vjudge
看数据范围很大,开数组会超内存,此题需要离散化
常见离散化

  1.  		for(int i=1;i<=n;i++)
     	{
     		scanf("%lld",&v[i].v);
     		v[i].id=i;
    
     	}
     	sort(v+1,v+1+n,cmpv);
     	int cnt=1;
     	for(int i=2;i<=n;i++)
     	{
     		if(v[i].v==v[i-1].v)v[i].v=cnt;
     		else v[i].v=(++cnt);
     	}
     	v[1].v=1;//这里一定要放最后,否则会出错
     	sort(v+1,v+1+n,cmpid);
    
  2. 	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&v[i].v);
    		a[i]=v[i].v;
    	}
    	sort(a+1,a+1+n);
    	int size = unique(a + 1, a + 1 + n)-(a + 1);
    	for(int i=1;i<=n;i++)
    	{
    		int t=lower_bound(a+1,a+1+n,v[i].v)-a;
    		v[i].v=t;
    	}
    

    剩下的就比较简单了,倒着在相应的值位置存入1,表示已经存在,如果a[i]<a[j]&&i>j就存 在逆序对了

    点击查看代码
    
      #include <iostream>
      #include <cstdio>
      #include <algorithm>
      #include <math.h>
      #include <string.h>
      #include <string>
      #include <cstring>
      #include <vector>
      #include <map>
      #include <stack>
      #define int long long 
      using namespace std;
      int n,a[500005],c[500005],N;//999999999
      struct ac
      {
    	int id,v;
      }v[500005];
      bool cmpid(ac a,ac b)
      {
    	return a.id<b.id;
      }
      bool cmpv(ac a,ac b)
      {
    	return a.v<b.v;
      }
      int lowbit(int x)
      {
    	return x&(-x);
      }
      void add(int x,int key)
      {
    	while(x<=n)
    	{
    		c[x]+=key;
    		x+=lowbit(x);
    	}
      }
      int gs(int x)
      {
    	int ans=0;
    	while(x)
    	{
    		ans+=c[x];
    		x-=lowbit(x);
    	}
    	return ans;
      }
      signed main()
      {
    	while(scanf("%lld",&n)!=EOF)
    	{
    		if(n==0)break;
    		memset(c,0,sizeof(c));
    		memset(a,0,sizeof(a));
    		memset(v,0,sizeof(v));
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%lld",&v[i].v);
    			v[i].id=i;a[i]=v[i].v;
    		}
    		sort(a+1,a+1+n);
    		int size = unique(a + 1, a + 1 + n)-(a + 1);
    		for(int i=1;i<=n;i++)
    		{
    			int t=lower_bound(a+1,a+1+n,v[i].v)-a;
    			v[i].v=t;
      //			if(v[i].v==v[i-1].v)v[i].v=cnt;
      //			else v[i].v=(++cnt);
    		}
      //		for(int i=1;i<=n;i++)cout<<v[i].v<<" ";
      //		cout<<endl;
    		int ans=0;
    		for(int i=n;i>=1;i--)
    		{
    			ans+=gs(v[i].v);
    			add(v[i].v+1,1);
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
      }
    
    
posted @ 2024-02-19 09:49  wlesq  阅读(3)  评论(0编辑  收藏  举报