Description
Input
Every test case consists of N + 1 integers. The first integer is N, the number of players. Then N distinct integers a1, a2 ... aN follow, indicating the skill rank of each player, in the order of west to east. (1 <= ai <= 100000, i = 1 ... N).
Output
Sample Input
1 3 1 2 3
Sample Output
1
const int MAXN = 20002;
int a[MAXN], ll[MAXN], rl[MAXN];//leftlower,rightlower
scanf("%d", &a[1]);
update(a[1], 1);
for (i = 2; i < n; i++)
{
scanf("%d", &a[i]);
update(a[i], 1);
ll[i] = sum(a[i] - 1);
}
scanf("%d", &a[n]);
//注意这里要清空树
memset(rank, 0, sizeof(rank));
update(a[n], 1);
for (i = n - 1; i > 1; i--)
{
update(a[i], 1);
rl[i] = sum(a[i] - 1);
}
2. 注意到在数列{aN}是递增或递减数列的情形时,取法数达到最大,为(N-2)(N-1)N/6,数据最大约10^15,所以这里用long long。
long long ans = 0;
for (i = 2 ; i < n; i++)
{
ans += ll[i] * (n - i - rl[i]) + (i - 1 - ll[i]) * rl[i];
}
完整代码:
/*UVa: 0.269s*/
/*POJ: 235ms,792KB*/
/*HDU: 109ms,904KB*/
#include<cstdio>
#include<cstring>
const int MAXN = 100002;
const int MAXN2 = 20002;
int rk[MAXN], a[MAXN2], ll[MAXN2], rl[MAXN2];
void update(int a, int val)
{
while (a <= MAXN)
{
rk[a] += val;
a += -a & a;
}
}
int sum(int a)
{
int sum = 0;
while (a > 0)
{
sum += rk[a];
a -= -a & a;
}
return sum;
}
int main()
{
int i, t, n;
long long ans;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
memset(rk, 0, sizeof(rk));
scanf("%d", &a[1]);
update(a[1], 1);
for (i = 2; i < n; i++)
{
scanf("%d", &a[i]);
update(a[i], 1);
ll[i] = sum(a[i] - 1);
}
scanf("%d", &a[n]);
memset(rk, 0, sizeof(rk)); ///注意这里要清空
update(a[n], 1);
for (i = n - 1; i > 1; i--)
{
update(a[i], 1);
rl[i] = sum(a[i] - 1);
}
ans = 0;
for (i = 2 ; i < n; i++)
ans += ll[i] * (n - i - rl[i]) + (i - 1 - ll[i]) * rl[i];
printf("%lld\n", ans);
}
return 0;
}
5395



被折叠的 条评论
为什么被折叠?



