NCPC 2012 Bread Sorting
逆序对数的应用;
逆序对数的写法有,二分,树状数组,分治;
学习一下;
树状数组版:
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=100010; 6 int a[maxn],b[maxn],c[maxn]; 7 int n; 8 struct point 9 { 10 int num,index; 11 bool operator<(const point& t)const 12 { 13 return num<t.num; 14 } 15 }p[maxn]; 16 17 int lowbit(int x) 18 { 19 return x&(-x); 20 } 21 22 void updata(int i,int x) 23 { 24 while(i<=n) 25 { 26 c[i]+=x; 27 i=i+lowbit(i); 28 } 29 } 30 31 int sum(int x) 32 { 33 int ans=0; 34 while(x>0) 35 { 36 ans+=c[x]; 37 x-=lowbit(x); 38 } 39 return ans; 40 } 41 42 int main() 43 { 44 int i,j; 45 while(scanf("%d",&n)!=EOF) 46 { 47 memset(c,0,sizeof c); 48 for(i=1;i<=n;i++) 49 { 50 scanf("%d",&p[i].num); 51 p[i].index=i; 52 } 53 sort(p+1,p+n+1); 54 for(i=1;i<=n;i++) 55 b[p[i].index]=i; 56 int ans1=0,ans2=0; 57 for(i=1;i<=n;i++) 58 { 59 updata(b[i],1); 60 ans1=ans1+(sum(n)-sum(b[i])); 61 } 62 memset(c,0,sizeof c); 63 memset(b,0,sizeof b); 64 for(i=1;i<=n;i++) 65 { 66 scanf("%d",&p[i].num); 67 p[i].index=i; 68 } 69 sort(p+1,p+n+1); 70 for(i=1;i<=n;i++) 71 b[p[i].index]=i; 72 for(i=1;i<=n;i++) 73 { 74 updata(b[i],1); 75 ans2=ans2+(sum(n)-sum(b[i])); 76 } 77 if(ans1%2==ans2%2) printf("Possible\n"); 78 else printf("Impossible\n"); 79 } 80 return 0; 81 }
分治版:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=100010; 5 int b[maxn],c[maxn]; 6 int n,cnt; 7 struct point 8 { 9 int num,index; 10 bool operator<(const point& t)const 11 { 12 return num<t.num; 13 } 14 }p[maxn]; 15 16 void merge_sort(int *a,int x,int y,int *t) 17 { 18 if(y-x>1) 19 { 20 int m=(y+x)/2; 21 int p=x,q=m,i=x; 22 merge_sort(a,x,m,t); 23 merge_sort(a,m,y,t); 24 while(p<m||q<y) 25 { 26 if(q>=y||(p<m&&a[p]<=a[q])) t[i++]=a[p++]; 27 else 28 { 29 t[i++]=a[q++]; 30 cnt+=m-p; 31 } 32 } 33 for(int i=x; i<y; i++)a[i]=t[i]; 34 } 35 } 36 int main() 37 { 38 int i,j; 39 while(scanf("%d",&n)!=EOF) 40 { 41 for(i=1;i<=n;i++) 42 { 43 scanf("%d",&p[i].num); 44 p[i].index=i; 45 } 46 sort(p+1,p+n+1); 47 for(i=1;i<=n;i++) 48 b[p[i].index]=i; 49 cnt=0; 50 merge_sort(b,1,n+1,c); 51 int ans1=cnt; 52 53 cnt=0; 54 for(i=1;i<=n;i++) 55 { 56 scanf("%d",&p[i].num); 57 p[i].index=i; 58 } 59 sort(p+1,p+n+1); 60 for(i=1;i<=n;i++) 61 b[p[i].index]=i; 62 merge_sort(b,1,n+1,c); 63 int ans2=cnt; 64 if(ans1%2==ans2%2) printf("Possible\n"); 65 else printf("Impossible\n"); 66 } 67 return 0; 68 }
线段树版的话就不写了,麻烦!