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 }
树状数组
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 }
也可以双指针做, 按端点排序后 一直找一个区间 当人数达到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 }

浙公网安备 33010602011771号