快期末考了,这周并没有多做什么题,写几道卡了好久的二分好了QAQ
借教室
用check判断每一个请求能否满足租借条件;
所以先特判一下最后一次请求,要是最后一次请求能满足就直接输出0就可以了;
check里边使用差分和前缀和,把这次请求及之前每次请求使得每天需要的教室数量前缀和,并且和每天能借出的教室数量比较做判断;
如果从第一次请求一直判断到最后一次请求太慢了,所以在请求次数上做二分,找到最后一个符合条件的请求,+1即可得到第一个不符合条件的请求次数,再输出就可以啦QWQ;
#include <bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e6+8;
long long r[N],d[N],s[N],t[N],dif[N],sum[N];
bool check(int mid)
{
for(int i=1;i<=n;i++)
dif[i]=0;
for(int i=1;i<=mid;i++){
dif[s[i]]+=d[i];
dif[t[i]+1]-=d[i];
}
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+dif[i];
if(sum[i]>r[i]) return 0;
}
return 1;
}
int search()
{
int l=0,r=N,mid;
while(l<r){
mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
return l;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>r[i];
}
for(int i=1;i<=m;i++){
cin>>d[i]>>s[i]>>t[i];
}
if(check(m)){
cout<<"0";
return 0;
}
cout<<"-1"<<"\n";
int ans=search();
cout<<ans+1;
}
Intersecting Intervals
- 先按照左端点从小到大的顺序排好;
- 然后从第一个到最后一个循环,每次通过二分找这一个及其后边的访问中从哪一个开始它的左端点在这个左端点的右边,即这之后的都不再相交;(不是我讲得真的好抽象?
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+12;
int n;
pair<int,int> a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].first>>a[i].second;
sort(a+1,a+n+1);
long long sum=0;
for(int i=1;i<=n;i++){
int l=i,r=n,mid;
while(l<r){
mid=l+r+1>>1;
if(a[mid].first<=a[i].second) l=mid;
else r=mid-1;
}
sum+=l-i;
}
cout<<sum;
return 0;
}
其实用结构体也可以欸QWQ;