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 }
View Code

 分治版:

 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 }
View Code

线段树版的话就不写了,麻烦!

posted @ 2013-10-26 20:58  Yours1103  阅读(350)  评论(0编辑  收藏  举报