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