题目链接:http://codeforces.com/problemset/problem/91/B
——————————————————————————————————————————————
题目大意:若 i<j ,ai>aj,则 ai需要有个权值,值为比该数小,且离该数最远的数字与该数的距离。计算各权值和
——————————————————————————————————————————————
题目思路:记录下各数原来的位置,并归并排序,再dp一下
——————————————————————————————————————————————
题目细节:
大数组需要开成全局变量,否则栈溢出
——————————————————————————————————————————————
源代码:
#include<stdio.h>
#include<stdlib.h>
struct at
{
long long num;
int sat;
}a[100010];
int satt[100010];
struct at t[100010];
void mergesort(int l,int r,struct at *t)
{
int i = 0,j = 0;
int k = 0;
if((r-l)>1)
{
int m = (l+r)/2;
mergesort(l,m,t);
mergesort(m,r,t);
i = l;j = m;k = l;
while(i<m || j<r)
{
if(j >=r ||(i<m && a[i].num<=a[j].num))
{
t[k].num = a[i].num;
t[k++].sat = a[i++].sat;
}
else
{
t[k].num = a[j].num;
t[k++].sat = a[j++].sat;
}
}
for(i = l;i<r;i++)
{
a[i].num = t[i].num;
a[i].sat = t[i].sat;
}
}
}
int main()
{
int n = 0,i = 0,j = 0;
scanf("%d",&n);
for(i = 1;i<=n;i++)
{
scanf("%lld",&a[i].num);
a[i].sat = i;
}
mergesort(1,n+1,t);
free(t);
int dp[100010];
dp[1] = a[1].sat;
for(i = 2;i<=n;i++)
dp[i] = dp[i-1]<a[i].sat? a[i].sat : dp[i-1];
satt[a[1].sat] = -1;
for(i = 2;i<=n;i++)
satt[a[i].sat] = a[i].sat>dp[i-1]? -1:(dp[i-1] - a[i].sat - 1);
for(i = 1;i<=n;i++)
printf("%d ",satt[i]);
return 0;
}