D
我们可以把公式变一下,变成 − ( a i − b i ) < ( a j − b j ) -(a_{i}-b_{i})<(a_{j}-b_{j}) −(ai−bi)<(aj−bj),然后我们就可以按照ai-bi的差进行从小到大的排序,然后用upper_bound去算一下,就可以了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#define int long long
using namespace std;
struct node
{
int x,y;
}s[200005];
int a[200005],b[200005],ans,n;
bool cmp(node xx,node yy)
{
return xx.x-xx.y<yy.x-yy.y;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%lld",&s[i].x);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&s[i].y);
}
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++)
{
a[i]=s[i].x-s[i].y;
}
for(int i=1;i<=n;i++)
{
int xx=upper_bound(a+1+i,a+n+1,-a[i])-(a);
ans+=n-xx+1;
}
cout<<ans;
}
E
设 f [ i ] [ j ] f[i][j] f[i][j]为第i次睡觉的时间是j点,然后暴力转移就可以了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int n,h,l,r,a[2005],f[2005][2005],ans=0;
int main()
{
cin>>n>>h>>l>>r;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(f,-0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<h;j++)
{
f[i][j]=max(f[i-1][(j-a[i]+h)%h]+(l<=j&&j<=r),f[i-1][(j-(a[i]-1)+h)%h]+(l<=j&&j<=r));
}
}
for(int i=0;i<h;i++)
{
ans=max(ans,f[n][i]);
}
cout<<ans;
}