COGS 2580(cdq分治求五维偏序)
第一维:排序
第二维:分治后标号处理
第三维:分治后标号处理
第四维:分治
第五维:树状数组
模板代码:
#include<map>
#include<set>
#include<ctime>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cassert>
#include<cstring>
#include<complex>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 50010;
struct Query
{
int d1,d2,d3,d4,d5,part1,part2;
}query[maxn],tmp2[maxn],tmp3[maxn],tmp4[maxn];
int n,bit[maxn]; LL ans;
int lowbit( int x ){ return x&(-x); }
void add( int x , int val )
{
for ( ; x<=n ; x+=lowbit(x) )
bit[x] += val;
}
int sum( int x )
{
int res = 0;
for ( ; x>=1 ; x-=lowbit(x) )
res += bit[x];
return res;
}
void clear( int x )
{
for ( ; x<=n ; x+=lowbit(x) )
{
if ( bit[x] ) bit[x] = 0;
else break;
}
}
void cdq4d( int L , int R )
{
if ( R-L<=1 ) return;
int M = ( L+R )>>1;
cdq4d( L , M );
cdq4d( M , R );
int p = L,q = M,o = L;
while ( p<M&&q<R )
{
if ( tmp3[p].d4<tmp3[q].d4 )
{
if ( tmp3[p].part1==0&&tmp3[p].part2==0 ) add( tmp3[p].d5 , 1 );
tmp4[o++] = tmp3[p++];
}
else
{
if ( tmp3[q].part1==1&&tmp3[q].part2==1 ) ans += sum( tmp3[q].d5 );
tmp4[o++] = tmp3[q++];
}
}
while ( p<M ) tmp4[o++] = tmp3[p++];
while ( q<R )
{
if ( tmp3[q].part1==1&&tmp3[q].part2==1 ) ans += sum( tmp3[q].d5 );
tmp4[o++] = tmp3[q++];
}
for ( int i=L ; i<R ; i++ )
{
clear( tmp4[i].d5 );
tmp3[i] = tmp4[i];
}
}
void cdq3d( int L , int R )
{
if ( R-L<=1 ) return;
int M = ( L+R )>>1;
cdq3d( L , M );
cdq3d( M , R );
int p = L,q = M,o = L;
while ( p<M&&q<R )
{
if ( tmp2[p].d3<tmp2[q].d3 )
tmp2[p].part2 = 0,tmp3[o++] = tmp2[p++];
else
tmp2[q].part2 = 1,tmp3[o++] = tmp2[q++];
}
while ( p<M ) tmp2[p].part2 = 0,tmp3[o++] = tmp2[p++];
while ( q<R ) tmp2[q].part2 = 1,tmp3[o++] = tmp2[q++];
for ( int i=L ; i<R ; i++ ) tmp2[i] = tmp3[i];
cdq4d( L , R );
}
void cdq2d( int L , int R )
{
if ( R-L<=1 ) return;
int M = (L+R)>>1;
cdq2d( L , M );
cdq2d( M , R );
int p = L,q = M,o = L;
while ( p<M&&q<R )
{
if ( query[p].d2<query[q].d2 )
query[p].part1 = 0,tmp2[o++] = query[p++];
else
query[q].part1 = 1,tmp2[o++] = query[q++];
}
while ( p<M )
query[p].part1 = 0,tmp2[o++] = query[p++];
while ( q<R )
query[q].part1 = 1,tmp2[o++] = query[q++];
for ( int i=L ; i<R ; i++ ) query[i] = tmp2[i];
cdq3d( L , R );
}
int main()
{
for ( ; scanf ( "%d" , &n )==1 ; )
{
for ( int i=1 ; i<=n ; i++ )
bit[i] = 0,query[i].d1 = i;
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &query[i].d2 );
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &query[i].d3 );
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &query[i].d4 );
for ( int i=1 ; i<=n ; i++ )
scanf ( "%d" , &query[i].d5 );
ans = 0; cdq2d( 1 , n+1 ); printf ( "%lld\n" , ans );
}
return 0;
}