| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
解题思路以及个人写法:BIT or 线段树/**
天空上的星星有各自的等级,其等级为所有在它下面且它左边的星星数量和
现在按照y升序,x升序的顺序给你一群星星的坐标,
要你输出0到N-1等级的星星数量为多少? 1<=N<=15000 0<=X,Y<=32000
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1
2
1
1
0
思路```
考虑输出新的(xi,yi)时,我们后面的输入的值肯定x或者y比当前值大,所以不用考虑计算
而之前输入的值一定满足处于下方(其y肯定不大于yi),那我们只需要考虑前面的点多少在左方,即在小于等于xi的有多少
如何快速判断小于等于xi有多少?------------
前缀和sum思想---BIT或者线段树,维护1~x,因为它们都需要避免x = 0的情况,而题目0<=X,Y<=32000,所以我们给所有的x+1
操作为区间查询,单点更新 BIT很香 线段树也行
空间够,无需离散化
**/
//BIT 140ms
#include<cstdio>
#include<string.h>
using namespace std;
const int MAX_N = 15005,MAX_X = 32005;
int num[MAX_N],N;
int BIT[MAX_X << 1];
int sum(int n){
int res = 0;
while(n > 0){
res += BIT[n];
n -= (n&-n);
}
return res;
}
void add(int n,int v){
while(n <= MAX_X){
BIT[n] += v;
n += (n&-n);
}
}
int solve_bit(int x,int y){
int now = sum(x+1);
add(x+1,1);
return now;
}
int main(){
while(~scanf("%d",&N)){
int x,y;
memset(num,0,sizeof(num));
memset(num,0,sizeof(BIT));
for(int i = 0;i < N;++i){
scanf("%d%d",&x,&y);
int sum = solve_bit(x,y);
num[sum]++;
}
for(int i = 0;i < N;++i){
printf("%d\n",num[i]);
}
}
return 0;
}
-----------------------------------------------------------------
//线段树 188ms
#include<cstdio>
#include<string.h>
using namespace std;
const int MAX_N = 15005,MAX_X = 32005;
int num[MAX_N],N;
int tree[MAX_X << 2];
void update(int node,int L,int R,int pos,int v){
if(L == R && L == pos){
tree[node] += v;
return;
}
int mid = L + R >> 1;
if(pos <= mid)
update(node << 1,L,mid,pos,v);
if(pos > mid)
update(node << 1 | 1,mid + 1,R,pos,v);
tree[node] = tree[node << 1] + tree[node << 1 | 1];
}
int query(int node,int L,int R,int l,int r){
if(l <= L && R <= r){
return tree[node];
}
int res = 0;
int mid = L + R >> 1;
if(l <= mid){
res += query(node << 1, L , mid,l,r);
}
if(r > mid){
res += query(node << 1 | 1,mid+1,R,l,r);
}
return res;
}
int main(){
while(~scanf("%d",&N)){
int x,y;
memset(tree,0,sizeof(tree));
for(int i = 0;i < N;++i){
scanf("%d%d",&x,&y);
int r = query(1,1,MAX_X,1,x+1);
num[r]++;
update(1,1,MAX_X,x+1,1);
}
for(int i = 0;i < N;++i){
printf("%d\n",num[i]);
}
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator