版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/85109856
地址:https://ac.nowcoder.com/acm/contest/297/C
思路:先将所有点的覆盖次数求出来,再求出点覆盖一次的前缀和以及没有覆盖的点个数Sum,之后遍历线段找出最小的覆盖一次的值即可。求点的覆盖次数时code1为先将所有的点按照左端点由小到大排序,在遍历一遍求得,实在过于麻烦。code2则用扫描线求解
Code 1:
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N=1e5+5;
const int MAX_M=1e5+5;
struct node{
int l,r;
int id;
bool operator<(const node &p)const{
return (l==p.l)?(r<p.r):(l<p.l);
}
};
int n,m;
node a[MAX_M];
int d[MAX_N],pre[MAX_N];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=m;a[i].id=i,++i)
cin>>a[i].l>>a[i].r;
sort(a+1,a+m+1);
int l1=1,l2=1;
for(int i=1;i<=m;++i)
{
l2=max(l2,a[i].l);
while(l2<l1){
if(d[l2]) d[l2]=2;
++l2;
}
l1=max(l1,a[i].l);
while(l1<=a[i].r){
d[l1++]=1;
}
}
int Sum=0;
for(int i=1;i<=n;++i)
{
pre[i]=pre[i-1];
if(d[i]==0) ++Sum;
if(d[i]==1) pre[i]=pre[i-1]+1;
}
int x,s1=0,s2=n+1;
for(int i=1;i<=m;++i)
{
x=pre[a[i].r]-pre[a[i].l-1];
if(s2>x){
s2=x; s1=a[i].id;
}else if(s2==x) s1=max(s1,a[i].id);
}
s2+=Sum;
cout<<s1<<" "<<s2<<endl;
return 0;
}
Code 2:
#include<iostream>
using namespace std;
typedef pair<int,int> pr;
const int MAX_N=1e5+5;
const int MAX_M=1e5+5;
int n,m;
pr a[MAX_M];
int d[MAX_N];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=m;++i)
{
cin>>a[i].first>>a[i].second;
++d[a[i].first];
--d[a[i].second+1];
}
for(int i=1;i<=n;++i)
d[i]+=d[i-1];
int Sum=0;
for(int i=1;i<=n;++i)
{
if(!d[i]) ++Sum;
if(d[i]!=1) d[i]=0;
d[i]+=d[i-1];
}
pr ans=pr{0,n+1};
int x;
for(int i=1;i<=m;++i)
{
x=d[a[i].second]-d[a[i].first-1];
if(ans.second>=x) ans=pr{i,x};
}
ans.second+=Sum;
cout<<ans.first<<" "<<ans.second<<endl;
return 0;
}
/*
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int,int> pr;
const int MAX_N=1e5+5;
const int MAX_M=1e5+5;
struct node{
int x,w;
bool operator<(const node &p)const{
return (x==p.x)?(w<p.w):(x<p.x);
}
};
int n,m;
pr b[MAX_M];
node a[MAX_M*2];
int d[MAX_N],pre[MAX_N];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int l,r,t=0;
for(int i=1;i<=m;++i)
{
cin>>b[i].first>>b[i].second;
a[t++]=node{b[i].first,1};
a[t++]=node{b[i].second+1,-1};
}
m*=2;
sort(a,a+m);
l=t=0;
for(int i=1;i<=n&&l<m;++i)
{
while(l<m&&a[l].x==i){
t+=a[l++].w;
}
d[i]=t;
}
int Sum=0;
for(int i=1;i<=n;++i)
{
pre[i]=pre[i-1];
if(d[i]==0) ++Sum;
if(d[i]==1) pre[i]=pre[i-1]+1;
}
int x,s1=0,s2=n+1;
m/=2;
for(int i=1;i<=m;++i)
{
x=pre[b[i].second]-pre[b[i].first-1];
if(s2>=x){
s2=x; s1=i;
}
}
s2+=Sum;
cout<<s1<<" "<<s2<<endl;
return 0;
}
*/