好吧,我承认我在家没怎么写代码,集训第一天就脑残了. . . . . .兴致勃勃的写完一种n*log n的结果是n^2的,TLE了N遍. . . . . .
题意:对于一颗星星,有多少颗在它的左下方,它的等级就是多少,最后输出各个等级的数量有多少。
思路:因为题目中已经说了Y是按升序给出的,所以我们只要统计在当前这颗星星之前有多少颗的X是小于当前这一颗,然后就变成了一维线段树的查询与维护。
需要注意的地方就是,线段树的数组下表是从1开始的。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <algorithm> #define LL long long #define PI (acos(-1.0)) #define EPS (1e-10) using namespace std; struct N { int x,y; }p[15010]; int st[150010]; void Init(int site,int l,int r) { if(l == r) { st[site] = 0; return ; } int mid = (l+r)>>1; Init(site<<1,l,mid); Init(site<<1|1,mid+1,r); } int level[15010]; int query(int site,int l,int r,int L,int R) { if(l == L && r == R) { return st[site]; } int mid = (L+R)>>1; if(r <= mid) return query(site<<1,l,r,L,mid); if(mid < l) return query(site<<1|1,l,r,mid+1,R); return query(site<<1,l,mid,L,mid) + query(site<<1|1,mid+1,r,mid+1,R); } void updata(int site,int s,int L,int R) { st[site]++; if(L >= R) return ; int mid = (L + R)>>1; if(s <= mid) updata(site<<1,s,L,mid); else updata(site<<1|1,s,mid+1,R); } int main() { int n,i; scanf("%d",&n); memset(level,0,sizeof(int)*(n+2)); Init(1,1,32001); for(i = 1; i <= n; ++i) { scanf("%d %d",&p[i].x,&p[i].y); level[query(1,1,p[i].x+1,1,32001)]++; updata(1,p[i].x+1,1,32001); } for(i = 0; i < n; ++i) { printf("%d\n",level[i]); } return 0; }