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