件名の説明:
割り当てられたタスクを完了した後、西は、楼蘭の古代都市の314西に来ました。
伝説によると、この土地の前に長い時間が(それ以前楼蘭の古代都市より)2つの部族、部族の崇拝ナイフ(「V」)、部族の礼拝のスペードを(「∧」)に住んでいた、と彼らが表現するためにV字状とした∧それぞれの部族のトーテム。
以下Kroraina 314ウエスト巨大壁画を発見では、壁画は、N及び垂直位置はペアワイズ互いに素である点の水平方向の位置を測定することにより求めた点Nを、標識されました。
情報は、N点の相対位置と壁画に含まれることが西314、したがってある組の座標に希望
(1、Y 1)、(2、Y 2)、...、(N、YN)、Y1〜YN配置は、nに1です。
314西は壁画がトーテムの番号が含まれて勉強するつもりです。
三点(I、YI)、(J、YJ)、(K、YK)を満足1≤i<J <k≤n及びYI> YJ、YJ <YK場合、Vは3点がトーテムを構成すると言われています。
三点(I、YI)、(J、YJ)、(K、YK)はトーテム^呼ば1≤i<J <k≤n及びYI <YJ、YJ> YK、3個のドットを満たす場合。
314西は2つの部族のトーテム中のnポイントの数を知りたいです。
そのため、あなたは数および∧Vの数を見つけるためのプログラムを記述する必要があります。
アイデア:
任意の位置私に尋ね、実際には、タイトルと一緒に行くためのアイデアは、それが彼らの大小よりも左右端の数であり、最終的に製品を合計することはできますが、データの量が暴力的な、大きすぎではありません。
第1の観察条件、私は逆の順序でことではありません<jとYI> YJ、
我々はそれを求めてフェンウィックツリーで、私が持っているバックのためにどのように多く、その数よりも若い(実際にまたはその逆)の質問を変換することができます。
アレイは、その後、逆再び解決、私の前で解決することができるされ、当然のことながら、それら自体よりも大きい(同じではない要素)より小さい合計に移動する以下自分の数よりもなっています
注:フェンウィックツリーの値を解くと、現在の位置の後ろにある自分自身の数よりも小さくなっています
#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof a)
#pragma warning (disable:4996)
#pragma warning (disable:6031)
using namespace std;
const int N = 201000;
int n;
typedef long long ll;
ll a[N], b[N];
ll c1[N], c2[N];
int lowbit(int x) {
return x & -x;
}
void add(int x) {
while (x <= n) {
b[x]++;
x += lowbit(x);
}
}
ll query(int x) {
ll res = 0;
while (x) {
res += b[x];
x -= lowbit(x);
}
return res;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", a + i);
}
// c1 : i 后面有多少个比它小
// c2 : i 前面有多少个比它小
mem(b, 0);
for (int i = n; i > 0; i--) {
c1[i] = query(a[i] - 1);
add(a[i]);
}
mem(b, 0);
for (int i = 1; i <= n; i++) {
c2[i] = query(a[i] - 1);
add(a[i]);
}
ll resv, res;
res = 0;
resv = 0;
for (ll i = 1; i <= n; i++) {
res += c1[i] * c2[i];
resv += (n - i - c1[i]) * (i - 1 - c2[i]);
}
printf("%lld %lld\n", resv, res);
return 0;
}