两种写法所用到的思维是一样的,都是在输入一个星星位置的时候,
先查询比他的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\n",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\n",level[i]);
}
return 0;
}
来源:https://www.cnblogs.com/tombraider-shadow/p/10998393.html