时间限制 : 10.000 sec 内存限制 : 32 MB

John loves to see the sky. A day has Q times. Each time John will find a new star in the sky, or he wants to know how many stars between(x1,y1,z1) and (x2,y2,z2).
输入
The first line contains a single integer T(1≤T≤10) (the data for Q>100 less than 6 cases), indicating the number of test cases.
The first line contains an integer Q(1≤Q≤50000),indicating how many times in a day.
Next Q lines contain some integers, first input an integer A(1≤A≤2).
If A=1 then input 3 integers x, y and z, indicating a coordinate of one star..
If A=2 then input 6 integersx1,y1,z1,x2,y2,z2(1≤x,y,z,x1,y1,z1,x2,y2,z2≤10^9,x1≤x2,y1≤y2,z1≤z2).
输出
For each “A=2”,output an integer means how many stars in such a section.
样例输入 Copy
2
11
1 1 1 1
2 1 1 1 1 1 1
1 2 2 2
1 1 1 2
2 1 1 1 2 2 2
1 3 3 3
1 4 4 4
1 5 5 5
1 6 6 6
2 1 1 1 6 6 6
2 3 3 3 6 6 6
11
1 1 1 1
2 1 1 1 1 1 1
1 2 2 2
1 1 1 2
2 1 1 1 2 2 2
1 3 3 3
1 4 4 4
1 5 5 5
1 6 6 6
2 1 1 1 6 6 6
2 3 3 3 6 6 6
样例输出 Copy
1
3
7
4
1
3
7
4

#pragma GCC optimize(2)

#include <cstdio>
#include <algorithm>
#include <cstring>

const int maxm=50000;
const int maxq=50000;
const int maxk=maxq<<3;
const int maxn=maxq*2+maxm;

int read()
{
  int x=0,f=1;
  char ch=getchar();
  while((ch<'0')||(ch>'9'))
    {
      if(ch=='-')
        {
          f=-f;
        }
      ch=getchar();
    }
  while((ch>='0')&&(ch<='9'))
    {
      x=x*10+ch-'0';
      ch=getchar();
    }
  return x*f;
}

struct data
{
  int op,pos,t,x,y,z,v;

  data(int _op=0,int _pos=0,int _t=0,int _x=0,int _y=0,int _z=0,int _v=0)
  {
    op=_op;
    pos=_pos;
    x=_x;
    y=_y;
    z=_z;
    v=_v;
    t=_t;
  }
};

bool cmpz(const data &a,const data &b)
{
  return a.z<b.z;
}

bool cmpt(const data &a,const data &b)
{
  return a.t<b.t;
}

bool cmpx(const data &a,const data &b)
{
  return a.x<b.x;
}

bool cmpy(const data &a,const data &b)
{
  return a.y<b.y;
}

int t,n,m,q,tot,ans[maxq+10],tmp[maxk+10];
data p[maxk+10],pp[maxk+10];

namespace tree
{
  int val[maxn+10];

  int lowbit(int x)
  {
    return x&(-x);
  }

  int add(int pos,int v)
  {
    while(pos<=n)
      {
        val[pos]+=v;
        pos+=lowbit(pos);
      }
    return 0;
  }

  int getsum(int pos)
  {
    int sum=0;
    while(pos)
      {
        sum+=val[pos];
        pos-=lowbit(pos);
      }
    return sum;
  }
}

int cdq(int l,int r)
{
  if(l==r)
    {
      return 0;
    }
  int mid=(l+r)>>1;
  cdq(l,mid);
  cdq(mid+1,r);
  std::sort(pp+l,pp+mid+1,cmpy);
  std::sort(pp+mid+1,pp+r+1,cmpy);
  int u=l;
  for(int i=mid+1; i<=r; ++i)
    {
      while((u<=mid)&&(pp[u].y<=pp[i].y))
        {
          if(!pp[u].op)
            {
              tree::add(pp[u].z,1);
            }
          ++u;
        }
      if(pp[i].op)
        {
          int v=tree::getsum(pp[i].z);
          ans[pp[i].pos]+=pp[i].v*v;
        }
    }
  for(int i=l; i<u; ++i)
    {
      if(!pp[i].op)
        {
          tree::add(pp[i].z,-1);
        }
    }
  return 0;
}

int solve(int l,int r)
{
  if(l==r)
    {
      return 0;
    }
  int mid=(l+r)>>1;
  solve(l,mid);
  solve(mid+1,r);
  std::sort(p+l,p+mid+1,cmpx);
  std::sort(p+mid+1,p+r+1,cmpx);
  int cnt=0,u=l,v=mid+1;
  while(v<=r)
    {
      while((u<=mid)&&(p[u].op))
        {
          ++u;
        }
      while((v<=r)&&(!p[v].op))
        {
          ++v;
        }
      if(v>r)
        {
          break;
        }
      if((u>mid)||(p[u].x>p[v].x))
        {
          pp[++cnt]=p[v++];
        }
      else
        {
          pp[++cnt]=p[u++];
        }
    }
  if(cnt)
    {
      cdq(1,cnt);
    }
  return 0;
}

int put(data d)
{
  if((d.x>0)&&(d.y>0)&&(d.z>0))
    {
      p[++n]=d;
    }
  return 0;
}

int main()
{
  t=read();
  while(t--)
    {
      memset(ans,0,sizeof ans);
      int f=0;
      n=0;
      q=read();
      for(int i=1; i<=q; ++i)
        {
          int op=read();
          if(op==1)
            {
              int x=read(),y=read(),z=read();
              p[++n]=data(0,0,i,x,y,z,0);
            }
          else
            {
              int lx=read(),ly=read(),lz=read(),rx=read(),ry=read(),rz=read();
              ++f;
              put(data(1,f,i,rx,ry,rz,1));
              put(data(1,f,i,lx-1,ry,rz,-1));
              put(data(1,f,i,rx,ly-1,rz,-1));
              put(data(1,f,i,lx-1,ly-1,rz,1));
              put(data(1,f,i,rx,ry,lz-1,-1));
              put(data(1,f,i,lx-1,ry,lz-1,1));
              put(data(1,f,i,rx,ly-1,lz-1,1));
              put(data(1,f,i,lx-1,ly-1,lz-1,-1));
            }
        }
      std::sort(p+1,p+n+1,cmpz);
      tmp[1]=1;
      for(int i=2; i<=n; ++i)
        {
          if(p[i].z!=p[i-1].z)
            {
              tmp[i]=tmp[i-1]+1;
            }
          else
            {
              tmp[i]=tmp[i-1];
            }
        }
      for(int i=1; i<=n; ++i)
        {
          p[i].z=tmp[i];
        }
      std::sort(p+1,p+n+1,cmpt);
      solve(1,n);
      for(int i=1; i<=f; ++i)
        {
          printf("%d\n",ans[i]);
        }
    }
  return 0;
}