Jaap, Jan, and Thijs are on a trip to the desert after having attended the ACM ICPC World Finals 2015 in Morocco. The trip included a camel ride, and after returning from the ride, their guide invited them to a big camel race in the evening. The camels they rode will also participate and it is customary to bet on the results of the race. One of the most interesting bets involves guessing the complete order in which the camels will finish the race. This bet offers the biggest return on your money, since it is also the one that is the hardest to get right.
Jaap, Jan, and Thijs have already placed their bets, but the race will not start until an hour from now, so they are getting bored. They started wondering how many pairs of camels they have put in the same order. If camel c is before camel d on Jaap’s, Jan’s and Thijs’ bet, it means that all three of them put c and d in the same order. Can you help them to calculate the number of pairs of camels for which this happened?
The input consists of:
The camels are numbered 1, … , n. Each camel appears exactly once in each bet.
Output the number of pairs of camels that appear in the same order in all 3 bets.
Sample input 1
3
3 2 1
1 2 3
1 2 3
Sample input 2
4
2 3 1 4
2 1 4 3
2 4 3 1
Sample output 1
0
Sample output 2
3
NWERC 2015 Problem G
题目要求在三个数列中“正序”的数对,可以将题目转变为求所有存在“逆序”的数对,然后从总可能中减去。后者就是一个简单求逆序对。
#include
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
inline int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
template<typename tn> void cmax(tn& a, tn b) { if (b > a) a = b; }
template<typename tn> void cmin(tn& a, tn b) { if (b < a) a = b; }
const int N = 333333;
int p1[N], p2[N], p3[N], pos[N], n;
ll c[N];
int lowbit(int x) { return x & (-x); }
int query(int x) { int ret = 0; while(x <= n) ret += c[x], x += lowbit(x); return ret; }
void update(int x) { while(x > 0) ++c[x], x -= lowbit(x); }
int main() {
freopen("G.in", "r", stdin);
freopen("G.out", "w", stdout);
n = read();
rep(i, 1, n) p1[i] = read();
rep(i, 1, n) p2[i] = read();
rep(i, 1, n) p3[i] = read();
memset(pos, 0, sizeof(pos));
ll ans = 0;
rep(i, 1, n) pos[p1[i]] = i;
rep(i, 1, n) ans += query(pos[p2[i]] + 1), update(pos[p2[i]]);
memset(c, 0, sizeof(c));
rep(i, 1, n) ans += query(pos[p3[i]] + 1), update(pos[p3[i]]);
memset(c, 0, sizeof(c));
rep(i, 1, n) pos[p2[i]] = i;
rep(i, 1, n) ans += query(pos[p3[i]] + 1), update(pos[p3[i]]);
printf("%lld\n", ((ll)n * (ll)(n - 1) - ans) / 2);
return 0;
}
难得做出一道脑洞题
开不出来的同学,为了做60pts,真的是各显神通