例题:poj2299
看代码就好了
树状数组:
#include<iostream> #include<cstdio> #include<queue> #include<string> #include<string.h> #include<set> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<iterator> #define mem(a,b) memset(a,b,sizeof(a)) #define MOD 100000007 #define ll long long #define INF 0x3f3f3f3f const double pi = acos(-1.0); const int Maxn=50000; using namespace std; inline int scan() { int x=0,c=1; char ch=' '; while((ch>'9'||ch<'0')&&ch!='-')ch=getchar(); while(ch=='-')c*=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar(); return x*c; } /**********************************树状数组+离散化*******************************/ ll c[500010]; ll n; ll lowbit(ll x){ return x&-x; } void add(ll i){ while(i<=n){ c[i]++; i+=lowbit(i); } } ll getnum(ll i){ ll num=0; while(i>0){ num+=c[i]; i-=lowbit(i); } return num; } struct node{ ll v,i; friend bool operator < (node a,node b){ return a.v<b.v; } }nd[500010]; int main(){ while(scanf("%lld",&n)&&n){ mem(nd,0); mem(c,0); map<int,int>mp; int v; ll k=0; for(int i=1;i<=n;i++){ scanf("%d",&v); if(!mp[v]){//要去重!!! nd[++k].v=v; nd[k].i=k; mp[v]=1; } } n=k; sort(nd+1,nd+n+1); ll ans=0; for(int i=1;i<=n;i++){ add(nd[i].i); ans+=(1ll*i-getnum(nd[i].i));//已插入i个数,getnum[nd[i].i]是比nd[i].i小的数的个数i-getnum[nd[i].i]就是i个数前比他大的数 } printf("%lld ",ans); } return 0; }
归并排序:
#include<iostream> #include<cstdio> #include<queue> #include<string> #include<string.h> #include<set> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<iterator> #define mem(a,b) memset(a,b,sizeof(a)) #define MOD 100000007 #define ll long long #define INF 0x3f3f3f3f const double pi = acos(-1.0); const int Maxn=50000; using namespace std; inline int scan() { int x=0,c=1; char ch=' '; while((ch>'9'||ch<'0')&&ch!='-')ch=getchar(); while(ch=='-')c*=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar(); return x*c; } int c[500010]; vector<int>vec; int n; ll ans; void mergersort(int l,int r){ if(l==r){ return ; } int mid=(l+r)>>1; mergersort(l,mid); mergersort(mid+1,r); vec.clear(); int q=l,p=mid+1; while(q<=mid&&p<=r){ if(c[q]<=c[p]){ vec.push_back(c[q++]); }else{ vec.push_back(c[p++]); ans+=(mid-q+1);///l~mid中剩余数的个数就是mid-q+1,而如果c[q]>c[p],那c[p]就要交换mid-q+1次 } } while(q<=mid) vec.push_back(c[q++]); while(p<=r) vec.push_back(c[p++]); q=l; for(int i=0;i<vec.size();i++){ c[q++]=vec[i]; } } int main(){ while(scanf("%d",&n)&&n){ ans=0; mem(c,0); for(int i=1;i<=n;i++){ scanf("%d",&c[i]); } mergersort(1,n); printf("%lld ",ans); } return 0; }