饺子发现身边危机四伏!有nn个人站在一维平面上,每个人的坐标为Ai,能量值为Bi。饺子有cc种方法可以推测出有多少人想吃饺子,请你求出每种方法可以得出的想吃饺子的人数。
Input
第一行两个值 n(n≤105),c(c≤10)n
接下来n行每行两个值Ai,Bi(1≤Ai≤109,1≤Bi≤104,Ai≤Aj) if Q__Q题目链接 接下来c行,每行包含三个数K,function
其中
K可能为gt
或者lt
,代表大于或者小于
function可能为min
,max
或者avg
,代表最小,最大或者平均
length是一个整数(1≤length≤109)
K,function,length的意思为对于第ii号人,如果Bi K于[Ai−length,Ai)范围内的所有人能量值的function值,说明该人想吃饺子,特别的如果范围内一个人也没有,则这个人不想吃饺子。
Output
对于每种方法,输出想吃饺子的人数
Sample Input
10 2
60 30
120 28
180 35
240 34
300 40
360 31
420 28
480 2
540 42
600 30
gt avg 7200
lt min 300
Sample Output
4
2
需要将区间[Ai−length,Ai) 处理到线段树的1--n区间上,由于A是升序排列的,所以二分查找到区间左端的下标
#include
#include
#include
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e5+7;
long long btree[400005];
int bmax[400005];
int bmin[400005];
int n,c;
int a[maxn];
int b[maxn];
void buildtree(int l,int r,int rt)//建树,rt为当前位置
{
if(l==r)
{
btree[rt]=b[l];
bmin[rt]=b[l];
bmax[rt]=b[l];
return ;
}
int mid=(l+r)>>1;;
buildtree(l,mid,rt*2);
buildtree(mid+1,r,rt*2+1);
btree[rt]=btree[rt*2]+btree[rt*2+1];
bmax[rt]=max(bmax[rt<<1],bmax[rt<<1|1]);
bmin[rt]=min(bmin[rt<<1],bmin[rt<<1|1]);
}
long long findsum(int l,int r,int rt,int ll,int rr)//查询区间的和,ll区间左端,rr区间右端
{
if(ll<=l&&r<=rr) return btree[rt];
int mid=l+(r-l)/2;
long long ans=0;
if(ll<=mid) ans+=findsum(l,mid,rt*2,ll,rr);
if(rr>mid) ans+=findsum(mid+1,r,rt*2+1,ll,rr);
return ans;
}
int findmax(int l,int r,int rt,int ll,int rr)
{
if(ll<=l&&r<=rr) return bmax[rt];
int mid=l+(r-l)/2;
int ans=-INF;
if(ll<=mid) ans=max(ans,findmax(l,mid,rt*2,ll,rr));
if(rr>mid) ans=max(ans,findmax(mid+1,r,rt*2+1,ll,rr));
return ans;
}
int findmin(int l,int r,int rt,int ll,int rr)
{
if(ll<=l&&r<=rr) return bmin[rt];
int mid=l+(r-l)/2;
int ans=INF;
if(ll<=mid) ans=min(ans,findmin(l,mid,rt*2,ll,rr));
if(rr>mid) ans=min(ans,findmin(mid+1,r,rt*2+1,ll,rr));
return ans;
}
int main()
{
int len;
char k[10];
char fun[10];
scanf("%d%d",&n,&c);
for(int i=1;i<=n;++i)
scanf("%d%d",&a[i],&b[i]);
buildtree(1,n,1);
while(c--)
{
int ans=0;
scanf("%s%s%d",k,fun,&len);
for(int i=1;i<=n;++i)
{
int le=lower_bound(a+1,a+1+n,a[i]-len)-a;
int ri=lower_bound(a+1,a+1+n,a[i])-a;
ri--;
if(le>ri) continue;
if(fun[1]=='i')
{
int mmin=findmin(1,n,1,le,ri);
//cout<mmin) ans++;
}
else
{
if(b[i]ave) ans++;
}
else
{
if(b[i]mmax) ans++;
}
else
{
if(b[i]