区间:
思路:
按左端点从小到大排序,之后判断能否合并or开辟新区间即可
#include <iostream>
#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define mem(f, x) memset(f,x,sizeof(f))
#define fo(i,a,n) for(int i=a;i<n;++i)
#define foo(i,a,n) for(int i=a;i<=n;++i)
const int INF = 0x3f3f3f3f;
using namespace std;
template<class T>inline void read(T &x){
x=0; char c=getchar(); bool f=0;
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(f)x=-x;
}
const int N=1e6+5;
struct li{
int x,y;
}a[N],ans[N];
bool cmp(li a,li b){
return a.x<b.x||(a.x==b.x)&&(a.y<b.y);
}
int main(){
memset(a,0,sizeof a);
memset(ans,0,sizeof ans);
int t,x,y;
cin>>t;
fo(i,0,t)
read(a[i].x),read(a[i].y);
int num=0;
sort(a,a+t,cmp);
int l=a[0].x,r=a[0].y;
for(int i=1;i<t;i++){
if(a[i].x<=r){
if(a[i].y>r)r=a[i].y;
}
else{
ans[num].x=l,ans[num++].y=r;
l=a[i].x,r=a[i].y;
}
}
//最后一段区间是无法更新的,特殊处理即可
ans[num].x=l,ans[num++].y=r;
fo(i,0,num)
cout<<ans[i].x<<" "<<ans[i].y<<endl;
}
打印收费:
注意数据满足S递增,Q递减即可
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e5+10;
int n,m;
LL s[maxn],p[maxn],prmin[maxn],pr[maxn];
int main(){
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++){
scanf("%d%d",&s[i],&p[i]);
pr[i]=s[i]*p[i];
}
LL ans=1e18;
prmin[n]=pr[n];
for(int i=n-1; i>=1; i--){//逆序
prmin[i]=min(prmin[i+1],pr[i]);
}
while (m--){
int x;
scanf("%d",&x);
// lower_bound:查找第一个大于或等于num的数字
// upper_bound:查找第一个大于num的数字
int posx=lower_bound(s+1,s+n+1,x)-s;
LL numx=0,numy=1e18;
if (s[posx]==x) numx=x*p[posx];
else numx=x*p[posx-1];//pos大了
if (prmin[posx]!=0) numy=prmin[posx];
printf("%lld\n",min(numy,numx));
}
}
赛车:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int a[N],mx[N];
inline bool mycmp(int x,int y){return x>y;}
int main(){
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1,mycmp);
mx[1]=a[1]+1;
for(int i=2;i<=n;i++)
mx[i]=max(mx[i-1],a[i]+i);
int ans=1;
for (int i=2;i<=n;i++) if (a[i]+n>=mx[i-1]) ans++;
cout<<ans;
return 0;
}
思路:
#include<bits/stdc++.h>
using namespace std;
#define MAXN 302000
int a[MAXN],sum[MAXN];
int lm[MAXN],rm[MAXN];
template<class T>inline void read(T &x){
x=0; char c=getchar(); bool f=0;
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(f)x=-x;
}
inline bool cmp(int a,int b){return a>b;}
int main(){
int n,ans=0;
read(n);
for (int i=1;i<=n;++i) read(a[i]);
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;++i) {
sum[i]=i+a[i];
lm[i]=max(lm[i-1],sum[i]);
}
for (int i=n;i;--i) rm[i]=max(rm[i+1],sum[i]);
for (int i=1;i<=n;++i)
if (a[i]+n>=lm[i] && a[i]+n>=rm[i]-1) ans++;
printf("%d",ans);
return 0;
}