首页 > 代码库 > [noip2013 d1t2]火柴排队

[noip2013 d1t2]火柴排队

看不出是逆序对...感觉药丸

首先要看出最优解就是两个数组均有序的时候

再对两个数组的下标求逆序对即可

归并&树状数组

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<ctype.h>
 6 #define MODD 99999997
 7 using namespace std;
 8 const int maxn=100100;
 9 int n,ans;
10 int a[maxn],b[maxn];
11 int data[maxn];
12 struct node{
13     int num,pos;
14 }store[maxn];
15 int read(){
16     int x=0,f=1;
17     char ch=getchar();
18     while (!isdigit(ch)){
19         if (ch==-) f=-1;
20         ch=getchar();
21     }
22     while (isdigit(ch)){
23         x=x*10+ch-0;
24         ch=getchar();
25     }
26     return x*f;
27 }
28 bool cmp(node a,node b){
29     return a.num<b.num;
30 }
31 void init(){
32     for (int i=1;i<=n;i++){
33         store[i].num=read();store[i].pos=i;
34     }
35     sort(store+1,store+n+1,cmp);
36     for (int i=1;i<=n;i++) a[i]=store[i].pos;
37     
38     for (int i=1;i<=n;i++){
39         store[i].num=read();store[i].pos=i;
40     }
41     sort(store+1,store+n+1,cmp);
42     for (int i=1;i<=n;i++) b[store[i].pos]=a[i];    
43 }
44 void merge(int l,int r){
45     if (l>=r) return;
46     int mid=(l+r)>>1;
47     merge(l,mid);
48     merge(mid+1,r);
49     int p1=l,p2=mid+1;
50     int tot=l;
51     while (p1<=mid&&p2<=r){
52         if (b[p1]<b[p2]) data[tot++]=b[p1++];
53         else {
54             ans+=mid-p1+1;ans%=MODD;
55             data[tot++]=b[p2++];
56         }
57     }
58     while (p1<=mid) data[tot++]=b[p1++];
59     while (p2<=r) data[tot++]=b[p2++];
60     for (int i=l;i<=r;i++) b[i]=data[i];
61 }
62 int main(){
63     memset(a,0,sizeof(a));
64     memset(b,0,sizeof(b));
65     n=read();
66     init();    
67     ans=0;
68     merge(1,n);
69     printf("%d\n",ans);
70     return 0;
71 }
View Code

 

[noip2013 d1t2]火柴排队