Input
Output
Sample Input
3 1 2 0 3 3 4 0
Sample Output
1 0 0
多的不加赘述,只说明一点:此题要求本质上是stars的变种。stars求的是位于左下角区域的星星数量,而将此题的s与e看作x坐标与y坐标的话,很明显求的就是左上角的奶牛数量(因为要求si<=sj 且ej≤ei)。因此将此题完全转化过去的关键在于,对输入的区间进行排序,之后按照y的降序排列,y相等时,按照x升序排列。
之后按照排序前的数据顺序判断即可,此处依靠id实现。具体还用到树状数组求和与修改,这是基本功能就不说了。
由于s与e可能为0,方便判断的情况下,分别+1。
#include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdlib> #include <string> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> using namespace std; struct node{ int x,y,id; }a[100005]; int val[100005],c[1000005]; int lowbit(int x){ return x&(-x); } bool cmp(node a,node b){ if (a.y!=b.y) { return a.y>b.y; } return a.x<b.x; } void add(int x,int num){ while (x<=100000) { c[x]+=num; x+=lowbit(x); } } int sum(int x){ int s=0; while (x) { s+=c[x]; x-=lowbit(x); } return s; } int main(){ int n; while (scanf("%d",&n),n) { memset(c, 0, sizeof(c)); memset(a, 0, sizeof(a)); for (int i=0; i<n; i++) { scanf("%d %d",&a[i].x,&a[i].y); a[i].id=i; a[i].x++; a[i].y++; } sort(a, a+n, cmp); val[a[0].id]=sum(a[0].x); add(a[0].x, 1); for (int i=1; i<n; i++) { if (a[i].x==a[i-1].x&&a[i].y==a[i-1].y) { val[a[i].id]=val[a[i-1].id]; } else val[a[i].id]=sum(a[i].x); add(a[i].x,1); } printf("%d",val[0]); for (int i=1; i<n; i++) { printf(" %d",val[i]); } printf("\n"); } return 0; }