两种写法所用到的思维是一样的,都是在输入一个星星位置的时候,
先查询比他的x小的星星,再把它插入到树or数组中。
线段树写法:
#include<iostream> #include<algorithm> #include<string.h> using namespace std; #define maxn 32000+10 int sum[maxn<<2],level[maxn]; int n; void update(int l,int r,int rt,int data) { sum[rt]++; if(l==r) return; int mid=(l+r)/2; if(data<=mid) update(l,mid,rt<<1,data); else update(mid+1,r,rt<<1|1,data); } int query(int left,int right,int l,int r,int rt) { if(left==l&&right==r) { return sum[rt]; } int mid=(l+r)/2; if(right<=mid) { return query(left,right,l,mid,rt<<1); } else if(left>mid) return query(left,right,mid+1,r,rt<<1|1); else return query(left,mid,l,mid,rt<<1)+query(mid+1,right,mid+1,r,rt<<1|1); } int main() { while(cin>>n) { int x,y; memset(level,0,sizeof(level)); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { cin>>x>>y; ++x; ++level[query(1,x,1,maxn,1)]; update(1,maxn,1,x); } for(int i=0; i<n; ++i) printf("%d ",level[i]); } return 0; }
#include<iostream> //数转数组写法 #include<algorithm> #include<string.h> using namespace std; #define maxn 32000+10 int n,c[maxn],level[15000+10]; void add(int x) { while(x<=maxn) { c[x]++; x+=x&(-x); } } int sum(int x) { int sum1=0; while(x) { sum1+=c[x]; x-=x&(-x); } return sum1; } int main() { while(cin>>n) { int x,y; memset(level,0,sizeof(level)); memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { cin>>x>>y; ++x; level[sum(x)]++; add(x); } for(int i=0; i<n; ++i) printf("%d ",level[i]); } return 0; }