10.04 T1 数据结构+二分

Description

Input

Output

输出一行一个整数,即答案。

Sample Input

6 3 2 0 3 1 1 3 4 2 0 4 5 5

Sample Output

2

Hint

【数据范围及约定】
 
 
 
 
80~95分:二分图匹配就可以了
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define N 2000005
 5 using namespace std;
 6 struct node{
 7     int u,v;
 8 }e[N];
 9 int cnt,first[N],nxt[N];
10 void add(int u,int v){
11     e[++cnt].u=u;
12     e[cnt].v=v;
13     nxt[cnt]=first[u];
14     first[u]=cnt;
15 }
16 int vis[N],matching[N];
17 bool match(int u){
18     for(int i=first[u];i;i=nxt[i]){
19         int v=e[i].v;
20         if(vis[v])continue;
21         vis[v]=1;
22         if(!matching[v]||match(matching[v])){
23             matching[v]=u;
24             return true;
25         }
26     }
27     return false;
28 }
29 int n;
30 int hun(){
31     int ans=0;
32     for(int i=1;i<=n;i++){
33         memset(vis,0,sizeof vis);
34         if(match(i))ans++;
35     }
36     return ans;
37 }
38 int A[100005],B[100005],C[100005],D[100005];
39 int main(){
40     freopen("guide.in","r",stdin);
41     freopen("guide.out","w",stdout);
42     int num;scanf("%d",&num);
43     scanf("%d",&n);
44     for(int i=1;i<=n;i++){
45         scanf("%d%d",&A[i],&B[i]);
46     }    
47     for(int i=1;i<=n;i++){
48         scanf("%d%d",&C[i],&D[i]);
49     }
50     for(int i=1;i<=n;i++){
51         for(int j=1;j<=n;j++){
52             if(A[i]<=C[j]&&B[i]<=D[j])add(i,j+n),add(j+n,i);
53         }
54     }
55     cout<<hun();
56     return 0;

100分:把x降序排序,然后逐个加进去,如果是洞口直接扔进去,是旅客就把数据结构里最小的大于它的y取出来匹配就可以了,可以证明最优

树状数组(nlog^2n)

code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define N 1000005
 5 using namespace std;
 6 struct node{
 7     int x,y,id;
 8 }e[N];
 9 bool cmp(const node &a,const node &b){
10     return a.x>b.x;
11 }
12 int c[N];
13 int lowbit(int x){
14     return x&(-x);
15 }
16 int n;
17 void add(int x,int v){
18     while(x<=200000){
19         c[x]+=v;
20         x+=lowbit(x);
21     }
22 }
23 int query(int x){
24 //    cout<<"from->"<<x<<'\n';
25     int ans=0;
26     while(x){//cout<<"from->"<<x<<'\n';
27         ans+=c[x];
28         x-=lowbit(x);
29     }
30 //    cout<<'\n';
31     return ans;
32 }
33 int main(){
34     int num;
35     cin>>num>>n;
36     for(int i=1;i<=n;i++){
37         cin>>e[i].x>>e[i].y;
38         e[i].x++;
39         e[i].y++;
40         e[i].id=0;
41     }
42     for(int i=1;i<=n;i++){
43         cin>>e[i+n].x>>e[i+n].y;
44         e[i+n].x++;
45         e[i+n].y++;
46         e[i+n].id=1;
47     }
48     int ans=0;
49     sort(e+1,e+2*n+1,cmp);
50     for(int i=1;i<=2*n;i++){
51         if(e[i].id)
52             add(e[i].y,1);
53         else{
54             int l=e[i].y,r=2*n;
55             if(query(r)-query(l-1)==0)continue;
56             int now;
57             while(l<=r){
58                 int mid=l+r>>1;
59                 if(query(mid)-query(l-1)==0)l=mid+1;
60                 else r=mid-1,now=mid;
61             }
62             add(now,-1);
63             ans++;
64         }
65     }
66     cout<<ans;
67     return 0;
68 }

multiset维护序列O(nlogn):

code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<set>
 5 #define N 1000005
 6 using namespace std;
 7 struct node{
 8     int x,y,id;
 9 }e[N];
10 bool cmp(const node &a,const node &b){
11     return a.x>b.x;
12 }
13 int c[N];
14 int lowbit(int x){
15     return x&(-x);
16 }
17 int n;
18 void add(int x,int v){
19     while(x<=200000){
20         c[x]+=v;
21         x+=lowbit(x);
22     }
23 }
24 int query(int x){
25 //    cout<<"from->"<<x<<'\n';
26     int ans=0;
27     while(x){//cout<<"from->"<<x<<'\n';
28         ans+=c[x];
29         x-=lowbit(x);
30     }
31 //    cout<<'\n';
32     return ans;
33 }
34 multiset<int>check;
35 int main(){
36     freopen("guide.in","r",stdin);
37     freopen("guide.out","w",stdout);
38     int num;
39     cin>>num>>n;
40     for(int i=1;i<=n;i++){
41         cin>>e[i].x>>e[i].y;
42         e[i].x++;
43         e[i].y++;
44         e[i].id=0;
45     }
46     for(int i=1;i<=n;i++){
47         cin>>e[i+n].x>>e[i+n].y;
48         e[i+n].x++;
49         e[i+n].y++;
50         e[i+n].id=1;
51     }
52     int ans=0;
53     sort(e+1,e+2*n+1,cmp);
54     for(int i=1;i<=2*n;i++){
55         if(e[i].id){
56             check.insert(e[i].y);
57         }
58         else{
59             if(!check.empty()){
60                 set<int>::iterator it=check.lower_bound(e[i].y);
61                 if(*it>=e[i].y)check.erase(*it),ans++;
62             }
63         }
64     }
65     cout<<ans;
66     return 0;
67 }

over

posted @ 2018-10-04 15:56  saionjisekai  阅读(43)  评论(0编辑  收藏  举报