「nwerc2015」赌骆驼

Source and Judge

Nwerc2015 Guessing Camels
bzoj4430

Record

1h

Analysis

请先思考后再展开

显然是个三维偏序,可以直接cdq,是log方的
然而又一种巧妙的log的做法
非法情况存在一种性质:每次取出两个排列的话,三种情况两种相同一种不同
不妨设 $PA_i > PA_j,PB_i < PB_j$
两两取出来,统计这个二维偏序,那么每队算重复一次,除以2,就是非法情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59


#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
typedef long long ll;
const int INF=0x3f3f3f3f;

const int MAX_N=210000;
int n;
int p[5][MAX_N];

int bit[MAX_N];
int (int x) {return x&-x;}
void change(int x,int c) {while(x<=n) bit[x]+=c,x+=lowbit(x);}
int ask(int x) {int ans=0;while(x>=1) ans+=bit[x],x-=lowbit(x);return ans;}

struct Nod{int x,y;}s[MAX_N];
bool cmp(Nod a,Nod b) {return a.x>b.x;}

ll ans=0;
void solve(int k1,int k2)
{
for(int i=1;i<=n;i++) s[i]=(Nod){p[k1][i],p[k2][i]};
sort(s+1,s+n+1,cmp);
memset(bit,0,sizeof bit);
for(int i=1;i<=n;i++) ans+=ask(s[i].y-1),change(s[i].y,1);
}
void main()
{
scanf("%d",&n);
for(int t=1;t<=3;t++) for(int i=1;i<=n;i++) {int x;scanf("%d",&x);p[t][x]=i;}
solve(1,2);solve(1,3);solve(2,3);
printf("%lld",(ll)n*(n-1)/2-ans/2);
}
};
int main()
{
mine::main();
}