三维点每个点参数a,b,c 找有多少对(node1,node2)点是 node1.a<node2.a&&node1.b<node2.b&&node1.c<node2.c
三维偏序关系,cdq裸题
#include <iostream>
#include <cstdio>
#include <algorithm>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define erp(i,a,b) for(int i=a;i>=b;--i)
#define clr(a) memset(a,0,sizeof a)
#define ll long long
using namespace std;
const int maxn=2e6+100;
const int N=2e6;
struct Node
{
int x,t,y; //下标是x;
};
Node tp[maxn],nodes[maxn];
int tree[maxn],mp1[maxn],mp2[maxn],mp3[maxn];
bool cmp(Node a,Node b)
{
return a.x<b.x;
}
void add(int index,int value)
{
while(index<=N)
{
tree[index]+=value;
index+=index&-index;
}
}
int finding(int index)
{
int sum=0;
while(index)
{
sum+=tree[index];
index-=index&-index;
}
return sum;
}
ll cdq(int L,int R);
int main()
{
int n,num;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num),mp1[num]=i;
for(int i=1;i<=n;i++)
scanf("%d",&num),mp2[num]=i;
for(int i=1;i<=n;i++)
scanf("%d",&num),mp3[num]=i;
for(int i=1;i<=n;i++)
{
nodes[i].x=mp1[i],nodes[i].t=mp2[i],nodes[i].y=mp3[i];
}
sort(nodes+1,nodes+1+n,cmp);
printf("%I64d\n",cdq(1,n));
return 0;
}
ll cdq(int L,int R)
{
if(L>=R)
return 0;
int mid=(L+R)/2,s1=L,s2=mid+1;
ll ans=0;
rep(i,L,R)
{
if(nodes[i].t<=mid)
tp[s1++]=nodes[i];
else
tp[s2++]=nodes[i];
}
rep(i,L,R) nodes[i]=tp[i];
s1=L;
rep(i,mid+1,R)
{
for(;s1<=mid&&nodes[s1].x<nodes[i].x;s1++) add(nodes[s1].y,1);
ans+=finding(nodes[i].y-1);
}
erp(i,s1-1,L) add(nodes[i].y,-1);
return ans=ans+cdq(L,mid)+cdq(mid+1,R);
}