http://hi.baidu.com/wjbzbmr/item/03de2de8d025eb07560f1dd0
设f(xxxx)表示排序xxx出现的数量。。
那么我们要求的是f(1324)-f(1243)-f(1432)
注意到f(1243)=f(12xx)-f(1234)。。这两个都很好求。。所以1243解决了。。
但其他两个几乎不可做啊。。题目既然让我们相减,这两个式子必然是有所关联的。。
f(1324)-f(1432)
我们尝试着在两边都+上一个f。。
(f(1324)+f(1423))-(f(1432)+f(1423))
=f(1x2x)-f(14xx)
这两个都是线段树可做的。。所以问题就解决了。。。
1x2x的做法是把所有数字从小到大加入序列。。
当加入数字x的时候,没有加入的就是空白,它一定比x大
对每个数字维护它后面的空白数量。
然后维护子段和。。
考虑当前加入的数字为2就差不多了。。
14xx的做法
所有数字从左到右加入按大小组成的序列。。。
那么考虑当前的数字为4.。那么xx必然是它和1之间的空白。。
那么维护每个数字后面的空白数量,的空白的数量的平方
并对这两个进行子段和的维护。。。。
代码完全抄袭某神
const int N = 200010, Mod = 16777216;
int n, Dat[N];
LL Cnt[N], Count[6][N], Ans;
inline void Input() {
scanf("%d", &n);
For(i, 1, n) scanf("%d", &Dat[i]);
}
inline void Plus(int x) {
Ans = (Ans + x) % Mod;
}
#define lowbit(x) ((x) & (-(x)))
inline void Change(LL *A, int V, LL Val) {
for( ; V <= n; V += lowbit(V)) A[V] += Val;
}
inline LL Ask(LL *A, int V) {
LL Ret = 0;
for( ; V; V -= lowbit(V)) Ret += A[V];
return Ret;
}
inline LL C(LL A, int B) {
if(A < B) return 0;
if(B == 2) return A * (A - 1) / 2;
return A * (A - 1) * (A - 2) / 6;
}
#undef lowbit
inline void Solve() {
Ans = 0;
Ford(i, n, 1) {
int T = Cnt[i] = Ask(Count[0], n) - Ask(Count[0], Dat[i]);
Plus(Ask(Count[2], n) - Ask(Count[2], Dat[i]) - C(T, 3));
Plus(T * (Ask(Count[3], Dat[i]) - C(Ask(Count[0], Dat[i]), 2)));
Change(Count[0], Dat[i], 1), Change(Count[1], Dat[i], T);
T = Ask(Count[1], n) - Ask(Count[1], Dat[i]);
Change(Count[2], Dat[i], T), Change(Count[3], Dat[i], Dat[i] - 1);
}
For(i, 1, n) {
int T = Ask(Count[4], Dat[i]);
Plus(Cnt[i] * (T * i - Ask(Count[5], Dat[i]) - C(T, 2)));
Change(Count[4], Dat[i], 1), Change(Count[5], Dat[i], i + 1);
}
cout << (Ans + Mod) % Mod;
}
int main() {
#ifndef ONLINE_JUDGE
SETIO("1145");
#endif
Input();
Solve();
return 0;
}