题解:P11197 [COTS/CETS 2021] 赛狗游戏 Tiket
思路分析
分别令
首先,对于所有满足条件的
事实上,我们可以将
和第一类二元组相结合,可以把第一维的限制去掉,这就是一个三维偏序的模板了。
观察数据范围,发现
其实三维偏序还存在一个
我们记
这个答案并不是三维偏序的对数,对于每一个三维偏序,我们都将其统计了
对于仅仅只有二维偏序的对数,我们将其统计了
有这么一个结论,三维偏序的对数和仅仅满足二维偏序的对数的和为总对数的一半。
证明:对于任意
所以对于任意
我们令
时间复杂度为
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int c[N],res,n;
struct node{int a,b,c;}q[N];
bool cmp_a(node a,node b){return a.a<b.a;}
bool cmp_b(node a,node b){return a.b<b.b;}
inline void read(int &a){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return a=x,void();
}
inline void add(int x,int t){
for(;x<=n;x+=(x&-x))c[x]+=t;
return;
}
inline int ask(int x){
int cnt=0;
for(;x>0;x-=(x&-x))cnt+=c[x];
return cnt;
}
signed main(){
read(n);
for(int i=1,x;i<=n;i++)read(x);
for(int i=1,x;i<=n;i++)read(x),q[x].a=i;
for(int i=1,x;i<=n;i++)read(x),q[x].b=i;
for(int i=1,x;i<=n;i++)read(x),q[x].c=i;
sort(q+1,q+1+n,cmp_a);
for(int i=1;i<=n;i++){
res+=ask(q[i].b);
add(q[i].b,1);
}
for(int i=1;i<=n;i++)add(q[i].b,-1);
for(int i=1;i<=n;i++){
res+=ask(q[i].c);
add(q[i].c,1);
}
for(int i=1;i<=n;i++)add(q[i].c,-1);
sort(q+1,q+1+n,cmp_b);
for(int i=1;i<=n;i++){
res+=ask(q[i].c);
add(q[i].c,1);
}
res=(res-(n*(n-1)/2))/2;
printf("%lld\n",res);
return 0;
}
参考:在
如有错误,请指出。