经欧阳讲解后我好像 似乎 理解了 资料
mergesort
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define ll long long #define rg register #define Max(x,y) (x)>(y)?(x):(y) #define Min(x,y) (x)>(y)?(y):(x) const int N=500000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827; int n,a[N],rk[N]; ll ans=0ll; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } void mergesort(int l,int r){ if(l>=r) return; int mid=(l+r)>>1,pl=l,pr=mid+1,k=l; mergesort(l,mid),mergesort(mid+1,r); while(pl<=mid&&pr<=r) if(a[pl]<=a[pr]) rk[k++]=a[pl++]; else rk[k++]=a[pr++],ans+=(ll)mid-pl+1; while(pl<=mid) rk[k]=a[pl],++k,++pl; while(pr<=r) rk[k]=a[pr],++k,++pr; for(int i=l;i<=r;++i) a[i]=rk[i]; } int main(){ // freopen("in.txt","r",stdin); rd(n); for(int i=1;i<=n;++i) rd(a[i]); mergesort(1,n); printf("%lld",ans); return 0; }
树状数组
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define ll long long #define rg register #define Max(x,y) (x)>(y)?(x):(y) #define Min(x,y) (x)>(y)?(y):(x) const int N=500000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827; ll n,a[N],tree[N<<1],b[N]; ll sum=0; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int lowbit(int x) {return x&(-x);} void update(int pos,int ad){ while(pos<=n) tree[pos]+=ad,pos+=lowbit(pos); } bool cmp(int x,int y){return a[x]==a[y]?x>y:a[x]>a[y];} ll query(int pos){ ll ans=0; while(pos>0) ans+=tree[pos],pos-=lowbit(pos); return ans; } int main(){ // freopen("in.txt","r",stdin); rd(n); for(int i=1;i<=n;++i) rd(a[i]),b[i]=i; sort(b+1,b+1+n,cmp); for(int i=1;i<=n;++i) update(b[i],1),sum+=query(b[i]-1);//比自己小且在自己后面 printf("%lld",sum); return 0; }
存一个只有50昏的动态开点
#include<bits/stdc++.h> using namespace std; #define Max(x,y) (x)<(y)?(y):(x) #define Min(x,y) (x)<(y)?(x):(y) #define ll long long #define rg register const int N=1e9,M=7e5+5,inf=0x3f3f3f3f,P=9999973; const int power=4,base=10000; ll n,a[M],cnt=1,lson[M],rson[M],sum[M]; ll ans=0; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } void pushup(int o){ sum[o]=sum[lson[o]]+sum[rson[o]]; } void add(int o,int l,int r,int k){ if(l>r) return; if(l==r){ ++sum[o]; return; } if(l>r) return; int mid=l+r>>1; if(k<=mid){ if(!lson[o]) lson[o]=++cnt; add(lson[o],l,mid,k); } else{ if(!rson[o]) rson[o]=++cnt; add(rson[o],mid+1,r,k); } pushup(o); } ll query(int o,int l,int r,int k){ if(!o||l>r) return 0; if(l==r) return sum[o]; int mid=l+r>>1; if(k<=mid) return query(lson[o],l,mid,k); else return sum[lson[o]]+query(rson[o],mid+1,r,k); } int main(){ freopen("in.txt","r",stdin); rd(n); for(int i=1;i<=n;++i) rd(a[i]); for(int i=n;i;--i){ ans+=query(1,1,N+5,a[i]-1); add(1,1,N+5,a[i]); } printf("%lld",ans); return 0; }