寒假第二周学习记录2 HDU5126 CDQ分治
大意:在一个三维空间当中,每次进行一个操作,添加一个点或者统计空间中的某一个长方体范围内的所有点
就是用CDQ分治就离线的统计出每个查询的结果
首先我们将每个点z坐标离散化,那么我们就可以利用树状数组统计出每个查询点之前插入的点的z坐标小于等于当前查询的点的个数。
那么我们就是要先将x,y序不大于当前查询,且时序小于当前查询的点先加入的树状数组当中,这一步操作我们需要进行一个嵌套的CDQ分治
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAX 500005
using namespace std;
struct Node
{
int x,y,z,p,t;
Node(){}
Node( int x , int y , int z , int p , int t )
:x(x),y(y),z(z),p(p),t(t){}
};
Node star[MAX];
Node star2[MAX];
Node star3[MAX];
int tree[MAX];
int lowbit ( int x )
{
return x&-x;
}
void add ( int i ,int x )
{
while ( i < MAX )
{
tree[i] += x;
i += lowbit(i);
}
}
int get ( int i )
{
int ans = 0;
while ( i )
{
ans += tree[i];
i -= lowbit ( i );
}
return ans;
}
int res[MAX];
void CDQ2 ( int l , int r )
{
if ( l == r ) return;
int mid = (l+r)/2;
CDQ2( l , mid );
CDQ2( mid+1 , r );
int l1 = l , r1 = mid+1;
while ( r1 <= r )
{
while ( l1 <= mid && star2[l1].y <= star2[r1].y )
{
if ( star2[l1].t == 0 ) add ( star2[l1].z , 1 );
l1++;
}
if ( star2[r1].t != 0 )
{
res[star2[r1].p] += get ( star2[r1].z ) * star2[r1].t;
}
r1++;
}
while ( l1 > l )
{
--l1;
if ( star2[l1].t == 0 ) add ( star2[l1].z , -1 );
}
l1 = l , r1 = mid+1;
for ( int i = l ; i <= r ; i++ )
if ( (l1 <= mid && star2[l1].y <= star2[r1].y) || r1 > r )
star3[i] = star2[l1++];
else star3[i] = star2[r1++];
for ( int i = l ; i <= r ; i++ )
star2[i] = star3[i];
}
void CDQ1 ( int l , int r )
{
if ( l == r ) return;
int mid = (l+r)/2;
CDQ1(l,mid);
CDQ1(mid+1,r);
int l1 = l , r1 = mid+1 , n = 0;
while ( r1 <= r )
{
while ( star[l1].t != 0 && l1 <= mid ) l1++;
while ( star[r1].t == 0 && r1 <= r ) r1++;
if ( r1 > r ) break;
if ( (star[l1].x <= star[r1].x && l1 <= mid ) || r1 > r )
star2[n++] = star[l1++];
else star2[n++] = star[r1++];
}
if ( n > 0 ) CDQ2(0,n-1);
l1 = l , r1 = mid+1;
for ( int i = l ; i <= r ; i++ )
{
if ( (star[l1].x <= star[r1].x && l1 <= mid )|| r1 > r )
star3[i] = star[l1++];
else star3[i] = star[r1++];
}
for ( int i = l ; i <= r ; i++ )
star[i] = star3[i];
}
int compn ( Node a, Node b )
{
return a.p < b.p;
}
int compz ( Node a , Node b )
{
return a.z < b.z;
}
int main ( )
{
int t,q,a,x1,y1,z1,x2,y2,z2;
scanf ( "%d" , &t );
while ( t-- )
{
int n = 0;
scanf ( "%d" , &q );
while ( q-- )
{
scanf ( "%d" , &a );
if ( a == 1 )
{
scanf ( "%d%d%d" , &x1 , &y1 , &z1 );
star[n++] = Node ( x1 , y1 , z1 , n , 0 );
}
else
{
scanf ( "%d%d%d%d%d%d" , &x1 , &y1 , &z1 , &x2 , &y2 , &z2 );
star[n++] = Node ( x2 , y2 , z2 , n , 1 );
star[n++] = Node ( x2 , y1-1 , z2 , n , -1 );
star[n++] = Node ( x1-1 , y2 , z2 , n , -1 );
star[n++] = Node ( x2 , y2 , z1-1 , n , -1 );
star[n++] = Node ( x1-1 , y1-1 , z2 , n , 1 );
star[n++] = Node ( x1-1 , y2 , z1-1 , n , 1 );
star[n++] = Node ( x2 , y1-1 , z1-1 , n , 1 );
star[n++] = Node ( x1-1 , y1-1 , z1-1 , n , -1 );
}
}
memset ( res , 0 , sizeof ( res ));
sort ( star , star+n , compz );
a = 1;
star[n].z = -1;
for ( int i = 0 ; i < n ; i++ )
if ( star[i].z != star[i+1].z )
star[i].z = a++;
else star[i].z = a;
sort ( star , star+n , compn );
CDQ1(0,n-1);
sort ( star , star+n , compn );
for ( int i = 0 ; i < n ; i++ )
{
if ( star[i].t != 0 )
{
int ans = 0;
for ( int j = 0 ; j < 8 ; j++ )
ans += res[i+j];
printf ( "%d\n" , ans );
i += 7;
}
}
}
return 0;
}