树状数组求逆序对 基础版+强化版本(去重+离散化)

 

是getsum(a[i]-1)

不是getsum(i-1);

20210920

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
int a[maxn],n,c[maxn],ans[maxn];
int lowbit(int x)
{
    return x&(-x);
}
int update(int id,int val)
{
    a[id]=val;
    while(id<=n)
     {  
         c[id]+=val;
         id+=lowbit(id);
     }
}
int getsum(int x)
{ int ans=0;
    while(x>0)
     {
         ans+=c[x];
         x-=lowbit(x);
     }
     return ans;
}
int main( )
{

   cin>>n;
   for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    

    
    for(int i=1;i<=n;i++)
    {
        update(a[i],1);
        ans[i]=i-getsum(a[i]-1);
        cout<<ans[i]<<" ";
    }    
    
}

 

强化版本,自己想的+手写的,因为看不懂也不想看洛谷那群家伙写的代码

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
long long b[maxn],n,c[maxn],vis[maxn];
struct node{
	long long val,id;
}a[maxn];
bool cmp(node a,node b)
{
	return a.val<b.val;
}
int lowbit(int x)
{
	return x&(-x);
}
void update(int id,int val)
{
	while(id<=n)
	 {  
	 	c[id]+=val;
	 	id+=lowbit(id);
	 }
}
long long getsum(int x)
{ long long ans=0;
	while(x>0)
	 {
	 	ans+=c[x];
	 	x-=lowbit(x);
	 }
	 return ans;
}
void pre( )
{
  memset(vis,0,sizeof(vis));
  memset(c,0,sizeof(c));
}
int main( )
{


   
	
//freopen("lyslys.in","r",stdin);
int t;
cin>>t;
while(t--)
{
	pre( );
   cin>>n;
	for(int i=1;i<=n;i++)
	{   cin>>a[i].val;
	    a[i].id=i;
	    //cout<<a[i]<<endl;
	/*	update(a[i],1);
		int x=i-getsum(a[i]-1)-1;
	   /* int y;
	    y=i-1-x;
	    if(x>y)
	    {
	    	ans[i]=1;
	    	//逆序的更多,放前面贪心 
		}
		else {
			ans[i]=0;
		}
		//这边要不要讨论==0的情况
		*/
	}
		
	sort(a+1,a+1+n,cmp);
	
	
	 int i,j;
	 long long cnt=0;
	 
	for(i=1;i<=n;)
	{   cnt++;
	    for(j=i+1;j<=n;j++)
	     {
	     	if(a[j].val==a[i].val)
	     	 {
			   a[j].val=cnt;
			 }
			 else break;
		 }
		 a[i].val=cnt;
		 i=j;
	}
	
	for(int k=1;k<=n;k++)
	{
		b[a[k].id]=a[k].val;
	}
	
	
	cnt=0;
	
	
	for(int i=1;i<=n;i++)
	{   
	    //cout<<a[i]<<endl;
		update(b[i],1);
		vis[b[i]]++;
		
		long long x,y;
		
		x=i-getsum(b[i]-1)-vis[b[i]];
	     
	    y=getsum(b[i]-1);
	    
	   // cout<<x<<" "<<y<<endl;
	    
	    cnt+=min(x,y);
	   /* int y;
	    y=i-1-x;
	    if(x>y)
	    {
	    	ans[i]=1;
	    	//逆序的更多,放前面贪心 
		}
		else {
			ans[i]=0;
		}
		//这边要不要讨论==0的情况
		*/
	   //cout<<x<<" ";
	}
	printf("%lld\n",cnt);
}

}

  

 

posted @ 2021-09-29 21:57  liyishui  阅读(44)  评论(0编辑  收藏  举报