【题目描述】
小卡卡顺着老者所指的方向,来到了Pascal神峰的顶峰。老者告诉小卡卡,Pascal山脉有很多座山,都排在一条直线上,每座山都有不同的高度。
Pascal山的山顶有一个神奇的洞穴,进入这个洞穴后,你将会到达这座山前方的另一座山,更加神奇的是,你到达的山一定比他所在的山高度要小。而Pascal圣地最大的宝藏就藏在某一座Pascal山上的洞穴中,这个洞穴的特点是它有一道石门封闭着。
小卡卡很想知道进入每座山的洞穴后,他所到达的不同的山会有多少种可能。
【输入格式】
第一行一个整数n,表示山的个数.(1<=n<=20000)
第二行以后n行从前到后给出每座山的高度。另外两座山可以有相同的高度.(1<=每座山的高度<=maxlongint)
【输出格式】
共n行,每行一个整数.第I行的整数表示他进入第I号山的洞穴后能够到达的不同的山的个数.
我们从前往后更新树状数组,后面的更小一定不会影响前面,山的高度过高,我们采用map映射
每次先查询所有比当前小的,在更新
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
using namespace std;
int n,a[20005],b[20005],cnt,tree[20005];
map<int,int> ma;
int sum(int x)
{
int ans=0;
while(x)
{
ans+=tree[x];
x-=(x&-x);
}
return ans;
}
void add(int x)
{
while(x<=cnt)
{
tree[x]++;
x+=(x&-x);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(!ma[a[i]]) ma[a[i]]=++cnt;
}
for(int i=1;i<=n;i++)
{
int now=ma[b[i]];
printf("%d\n",sum(now-1));
add(now);
}
}