一看题第一想法。。循环啊。。。一看数据循环肯定超时啊。。。呵呵了。
然后就是一个排序的问题了吧。。。。大概是这样的
给出一串1-n各种排列的数,求出满足i<j<k,且a[i]<a[k]<a[j]
要求是求(x,y,z)可以先求出(x,y,z)(x,z,y)的总和然后再减去后面的情况。两种情况的总和就是(对于数x来说),总共有C(x,2)即x*(x-1)/2种情况。
求比一个数小的数就是树状数组了啊。。然后大的数就是各种减。。恩
然后再求出i<j<k,a[i]<a[j]<a[k]的数目减去就行了。。。。
上代码。。。。
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn=100010;
const long long mode=100000007;
int n,c[maxn];
int lowbit(int x)
{
return x & (-x);
}
int getsum(int i) {
int result=0;
while (i>0) {
result+=c[i];
i-=lowbit(i);
}
return result;
}
void update(int i,int val)
{
while(i<=n)
{
c[i]+=val;
i+=lowbit(i);
}
}
int main()
{
int T, t;
long long ans, s, p;
scanf("%d", &T);
for (int cas=1; cas<=T; cas++) {
scanf("%d", &n);
memset(c, 0, sizeof(c));
ans = 0, s = 0;
for (int i=0; i<n; i++) {
scanf("%d", &t);
p = getsum(t);
ans = (ans + (long long)(n-t-i+p)*(n-t-i+p-1)/2) % mode;
s = (s + (long long)(n-t-i+p)*p) % mode;
update(t,1);
}
printf("Case #%d: %lld\n", cas, (ans+mode-s) % mode);
}
return 0;
}
你萌不能这样。。。。不能这样。。。我说不出来话还是程学长讲。。。。。= =还是等着程学长讲吧。。。。这题真是。。。。现在我都说不出来话了。。。。。