树状数组求逆序对 基础版+强化版本(去重+离散化)
是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);
}
}

浙公网安备 33010602011771号