象限查询

时间:2012-05-18 18:57:18

标签: c++ c algorithm data-structures

我几乎已经使用具有延迟传播的分段树解决了Interviewstreet的象限查询问题,但我仍然得到错误的答案,所以我需要在我的代码中提供帮助。

这就是问题:

象限查询

飞机上有N个点。第i个点具有坐标(xi,yi)。执行以下查询:

  1. 反映i点和j点之间的所有点,包括沿X轴。此查询表示为X i j
  2. 反映i点和j点之间的所有点,包括沿Y轴。此查询表示为Y i j
  3. 计算点i和j之间的点数,包括4个象限中的每一个。此查询表示为C i j
  4. 输入:

    第一行包含N,即点数。 N行跟随。

    第i行包含由空格分隔的xi和yi。

    下一行包含Q查询的数量。下一个Q行每个包含一个查询,其中一个是上述形式之一。

    所有指数均为1个索引。

    输出:

    为类型C i j的每个查询输出一行。对应的行包含4个整数;分别在第1,第2,第3和第4象限中具有[i..j]范围内的指数的点数。

    约束:

    1 <= N <= 100000
    1 <= Q <= 100000
    You may assume that no point lies on the X or the Y axis.
    All (xi,yi) will fit in a 32-bit signed integer
    In all queries, 1 <=i <=j <=N
    

    样本输入:

    4
    1 1
    -1 1
    -1 -1
    1 -1
    5
    C 1 4
    X 2 4
    C 3 4
    Y 1 2
    C 1 3
    

    样本输出:

    1 1 1 1
    1 1 0 0
    0 2 0 1
    

    说明:

    当查询显示X i j时,意味着获取索引i和j之间的所有点,包括并反映沿X轴的那些点。这里的i和j与点的坐标无关。他们是指数。我指的是点i,j指的是点j

    C 1 4要求你'考虑{1,2,3,4}中有索引的点集。在这些点中,有多少分别位于第1,第2,第3和第4个四边形?对此的答案显然是1 1 1 1。

    接下来,我们沿X轴反映指数'2 4'之间的点。所以新的坐标是:

    1 1
    -1 -1
    -1 1
    1 1
    

    现在C 3 4是'考虑在{3,4}中具有索引的点集。在这些点中,有多少分别位于第1,第2,第3和第4个四边形?点3位于象限2中,点4位于象限1中。因此答案是1 1 0 0。

    当前代码

    这是我在c中的解决方案:

    void query(int node, int b, int e, int i, int j, char ch)
    {
    
          if(L[node][0]!=0 || L[node][1]!=0)
        {
          if(b!=e){
          L[2*node+1][0]=L[node][0];
          L[2*node+1][1]=L[node][1];
          L[2*node+2][0]=L[node][0];
          L[2*node+2][1]=L[node][1];
          }
          if(L[node][0]%2!=0)
          {
          tmp=Q[node][0];
          Q[node][0]=Q[node][3];
          Q[node][3]=tmp;
    
          tmp=Q[node][1];
          Q[node][1]=Q[node][2];
          Q[node][2]=tmp;
          }
          if(L[node][1]%2!=0)
          {
          tmp=Q[node][0];
          Q[node][0]=Q[node][1];
          Q[node][1]=tmp;
    
          tmp=Q[node][2];
          Q[node][2]=Q[node][3];
          Q[node][3]=tmp;
          }
          L[node][0]=0;
          L[node][1]=0;
    
        }
    
          if (i > e || j < b)
              return ;
    
    
          if (b >= i && e <= j)
          {
        if(ch == 'C'){
        ans[0]+=Q[node][0];
        ans[1]+=Q[node][1];
        ans[2]+=Q[node][2];
        ans[3]+=Q[node][3];
        }
        if(ch == 'X')
        {
          if(b!=e){
          L[2*node+1][0]++;
          L[2*node+2][0]++;
          }
          tmp=Q[node][0];
          Q[node][0]=Q[node][3];
          Q[node][3]=tmp;
          tmp=Q[node][1];
          Q[node][1]=Q[node][2];
          Q[node][2]=tmp;
        }
        if(ch == 'Y')
        {
          if(b!=e){
          L[2*node+1][1]++;
          L[2*node+2][1]++;
          }
          tmp=Q[node][0];
          Q[node][0]=Q[node][1];
          Q[node][1]=tmp;
          tmp=Q[node][2];
          Q[node][2]=Q[node][3];
          Q[node][3]=tmp;
        }
        return ;
          }
    
    
           query(2 * node +1, b, (b + e) / 2, i, j,ch);
          query(2 * node + 2, (b + e) / 2 + 1, e, i, j,ch);
    
    
        Q[node][0]=Q[2*node+1][0] + Q[2*node+2][0];
        Q[node][1]=Q[2*node+1][1] + Q[2*node+2][1];
        Q[node][2]=Q[2*node+1][2] + Q[2*node+2][2];
        Q[node][3]=Q[2*node+1][3] + Q[2*node+2][3];
        return ;
    }
    

1 个答案:

答案 0 :(得分:1)

如果我正确理解你的算法,你正在使用L数组来跟踪是否需要翻转一系列点,而是推迟实际的翻转,直到它变得必要。

在这种情况下,我认为这些行可能存在问题:

void query(int node, int b, int e, int i, int j, char ch)
{
  if(L[node][0]!=0 || L[node][1]!=0)
  {
    if(b!=e){
      L[2*node+1][0]=L[node][0];
      L[2*node+1][1]=L[node][1];
      L[2*node+2][0]=L[node][0];
      L[2*node+2][1]=L[node][1];
    }

假设L [node] [0]为1,L [2 * node + 1] [0]已经为1.这意味着前面的某个步骤想要在2 * node + 1处翻转节点,然后这一步也想要翻转这些节点。这些翻转应该抵消,L [2 * node + 1] [0]应该为零。

我认为您应该更改这些行以使用xor,以便双击将取消:

void query(int node, int b, int e, int i, int j, char ch)
{
  if(L[node][0]!=0 || L[node][1]!=0)
  {
    if(b!=e){
      L[2*node+1][0]^=L[node][0];
      L[2*node+1][1]^=L[node][1];
      L[2*node+2][0]^=L[node][0];
      L[2*node+2][1]^=L[node][1];
    }

(或许我误解了这种方法!)