Exam Results ###K ###K //K

题目链接:https://vjudge.net/contest/402831#overview

题意:给定n个人 每个人有两种可能的成绩, 给定一个百分比  p%   所有人都要二选一 一个分数,问所有人中的最高分乘上p%的分数为及格线  问最多多少个人及格

思路:先考虑二分发现每单调性, 考虑枚举发现重复的部分很难处理,  区间的重复部分如何处理 很容易想到了扫描线, 分左右端点, 左端点进来 就加

等到右端点进来的时候就把左端点的贡献删去, 每次询问即可, 可以考虑直接multiset维护 或者线段树和树状数组维护

不要用 ceil  可能会出现精度问题

set的最好写

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pi pair<int,int>
 5 #define pb push_back
 6 #define fi first
 7 #define sc second
 8 #define ull unsigned long long
 9 const int maxn=4e5+10;
10 const int mod=998244353;
11 
12 
13 pi a[maxn];
14 
15 int main()
16 {
17     ios::sync_with_stdio(0);
18     cin.tie(0);
19     int t;cin>>t;
20     for(int c=1;c<=t;c++)
21     {
22         int n,p;
23         cin>>n>>p;
24         for(int i=1,j=0;i<=n;i++)
25         {
26             int l,r;cin>>l>>r;
27             swap(l,r);
28             a[++j]={l,0};
29             a[++j]={r,l};
30         }
31         sort(a+1,a+1+n*2);
32         int cnt=0;
33         int ans=0;
34         multiset<int>s;
35         for(int i=1;i<=n*2;i++)
36         {
37             int k=a[i].sc;
38             if(!k)
39             {
40                 cnt++;
41             }
42             else
43             {
44                 if(s.find(k)!=s.end())
45                 s.erase(s.find(k));
46             }
47             s.insert(a[i].fi);
48             int ck=(1ll*a[i].fi*p+100-1)/100;
49             while(*s.begin()<ck) s.erase(s.begin());
50             if(cnt==n) ans=max(ans,(int)s.size());
51         }
52         cout<<"Case #"<<c<<": "<<ans<<'\n';
53     }
54 
55 
56 
57 
58 
59 
60 }
View Code

树状数组

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pb push_back
  5 const int maxn =2e5+10;
  6 const int mod=998244353;
  7 int n,p;
  8 int tot;
  9 struct ac
 10 {
 11     int v,f,l;
 12     bool operator<(ac a)
 13     {
 14         //if(v==a.v) return f<a.f;
 15         return v<a.v;
 16     }
 17 };
 18 ac a[maxn*2];
 19 
 20 int tree[maxn*2];
 21 vector<int>v;
 22 int num(int x)
 23 {
 24     return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
 25 }
 26 
 27 int lowbits(int x)
 28 {
 29     return x&-x;
 30 }
 31 
 32 void add(int x,int k)
 33 {
 34     while(x<=tot)
 35     {
 36         tree[x]+=k;
 37         x+=lowbits(x);
 38     }
 39 }
 40 
 41 int query(int x)
 42 {
 43     int ans=0;
 44     while(x)
 45     {
 46         ans+=tree[x];
 47         x-=lowbits(x);
 48     }
 49     return ans;
 50 }
 51 
 52 
 53 
 54 int main()
 55 {
 56     ios::sync_with_stdio(false);
 57     cin.tie(0);
 58     int t;
 59     cin>>t;
 60     int cnt=0;
 61     while(t--)
 62     {
 63         cin>>n>>p;
 64         v.clear();
 65         tot=0;
 66         for(int i=1;i<=n;i++)
 67         {
 68             int l,r;
 69             cin>>r>>l;
 70             a[++tot].v=l;
 71             a[tot].f=0;
 72             a[++tot].v=r;
 73             a[tot].f=1;
 74             a[tot].l=a[tot-1].v;
 75             v.pb(l);
 76             v.pb(r);
 77         }
 78         sort(v.begin(),v.end());
 79         v.erase(unique(v.begin(),v.end()),v.end());
 80         for(int i=1;i<=tot;i++)
 81             tree[i]=0;
 82         sort(a+1,a+1+tot);
 83         int sum=0;
 84         int ans=0;
 85         for(int i=1;i<=tot;i++)
 86         {
 87             if(a[i].f==0)
 88             {
 89                 add(num(a[i].v),1);
 90                 sum++;
 91             }
 92             else
 93             {
 94                 add(num(a[i].v),1);
 95                 add(num(a[i].l),-1);
 96             }
 97             //int x=(1ll*p*a[i].v+100-1)/100;
 98             int x=ceil(p/100.0*a[i].v);
 99             if(sum==tot/2)
100             ans=max(ans,query(num(a[i].v))-query(num(x)-1));
101         }
102         
103         cout<<"Case #"<<++cnt<<": "<<ans<<'\n';
104         
105 
106 
107     }
108 
109 
110 
111 
112 
113 
114 
115 }
View Code

 

也可以双指针做, 按端点排序后 一直找一个区间 当人数达到n后就可以更新ans

需要用一个sub 来维护 两个端点同时在一个区间内减去重复的即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=4e5+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define pi pair<int,int>
 7 #define fi first
 8 #define sc second
 9 #define pb push_back
10 
11 struct ac
12 {
13     int v,f,id;
14     bool operator<(ac a)
15     {
16         return v<a.v;
17     }
18 };
19 ac a[maxn];
20 int vis[maxn];
21 
22 
23 
24 int main()
25 {
26     ios::sync_with_stdio(0);
27     cin.tie(0);
28     int t;
29     cin>>t;
30     int c=0;
31     while(t--)
32     {
33         int n,p;
34         cin>>n>>p;
35         int tot=0;
36         int sum=0;
37         int ans=0;
38         int sub=0;
39         for(int i=1;i<=n;i++)
40         {
41             int r,l;
42             cin>>r>>l;
43             a[++tot]={r,1,i};
44             a[++tot]={l,0,i};
45         }
46         for(int i=1;i<=n;i++) vis[i]=0;
47         sort(a+1,a+1+tot);
48         int j=1;
49         for(int i=1;i<=tot;i++)
50         {
51             int v=a[i].v,f=a[i].f,id=a[i].id;
52             if(!f) sum++,vis[id]=1;
53             else
54             {
55                 if(vis[id]) sub++,vis[id]=2;
56             }
57             int d=(1ll*v*p+100-1)/100;
58             while(j<i&&a[j].v<d)
59             {
60                 if(!a[j].f)
61                 {
62                     if(vis[a[j].id]==2)
63                         sub--;
64                     else
65                         vis[a[j].id]=0;
66                 }
67                 j++;
68             }
69             //cout<<sum<<" "<<i<<'\n';
70             if(sum==n) ans=max(ans,i-j+1-sub);
71         }
72         cout<<"Case #"<<++c<<": "<<ans<<'\n';
73     }
74 
75 
76 
77 
78 
79 
80 }
View Code

 

posted @ 2020-10-19 23:08  canwinfor  阅读(143)  评论(0)    收藏  举报