链接:https://ac.nowcoder.com/acm/contest/6013/C
来源:牛客网
牛牛种花
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld题目描述
牛牛看到家里的花圃空荡荡的,花圃是无限大的矩阵(有钱就是任性)。于是他就去买了n朵花。牛牛会把第i朵花种在(xi, yi)位置。然后牛牛有m次询问,他想知道在(ai,bi)坐标的左下角(x<=ai &&y<=bi)种了多少朵花。同一个地方可以种多朵花。
输入描述:
第一行,输入一个n和m。(1≤n、m≤105)
接下来n行,每一行输入两个整数xi,yi表示花要种植的坐标。
接下来m行,输入两个整数ai,bi表示要询问的坐标。(10-9≤xi、yi、ai、bi≤109)
输出描述:
输出有m行,每行对应一次询问的答案。示例1
输入
复制3 2 1 1 1 1 1 4 1 1 2 5
3 2 1 1 1 1 1 4 1 1 2 5输出
复制2 3
2 3说明
(1,1)处有两朵花,(1,4)处有一朵花解法:坐标离散化 ,离线处理询问,排序后,一边遍历一边维护线段树。
#include<bits/stdc++.h>
#define ls o*2
#define rs o*2+1
#define mid (l+r)/2
using namespace std;
int n,m;
struct node
{
int x,y,p,id;
}N[200005];
int cnt=0;
int X[200005],Y[200005];
int lx,ly=0;
int ans[100005];
int cmp(node & a,node & b)
{
return a.x<b.x||a.x==b.x&&a.y<b.y;
}
int tree[800005];
void up(int o,int l,int r,int pos)
{
if(l==r)
{
tree[o]++;
return ;
}
if(pos<=mid) up(ls,l,mid,pos);
else up(rs,mid+1,r,pos);
tree[o]=tree[ls]+tree[rs];
}
int qu(int o,int l ,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
return tree[o];
}
int ans=0;
if(ql<=mid) ans+=qu(ls,l,mid,ql,qr);
if(mid<qr) ans+=qu(rs,mid+1,r,ql,qr);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
X[lx++]=x;
Y[ly++]=y;
N[cnt++]={x,y,0};
}
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
X[lx++]=x;
Y[ly++]=y;
N[cnt++]={x,y,1,i};
}
sort(X,X+lx);
sort(Y,Y+ly);
lx=unique(X,X+lx)-X;
ly=unique(Y,Y+ly)-Y;//先排序!!!!
for(int i=0;i<cnt;i++)
{
N[i].x=lower_bound(X,X+lx,N[i].x)-X+1;
N[i].y=lower_bound(Y,Y+ly,N[i].y)-Y+1;
}
sort(N,N+cnt,cmp);
for(int i=0;i<cnt;i++)
{
if(N[i].p==0)
{
up(1,1,ly,N[i].y);
}
else
{
ans[N[i].id]=qu(1,1,ly,1,N[i].y);
}
}
for(int i=0;i<m;i++)
{
printf("%d\n",ans[i]);
}
}