Skip to content
Programmingoneonone
Programmingoneonone

LEARN EVERYTHING ABOUT PROGRAMMING

  • Home
  • CS Subjects
    • IoT ? Internet of Things
    • Digital Communication
    • Human Values
  • Programming Tutorials
    • C Programming
    • Data structures and Algorithms
    • 100+ Java Programs
    • 100+ C Programs
  • HackerRank Solutions
    • HackerRank Algorithms Solutions
    • HackerRank C problems solutions
    • HackerRank C++ problems solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
Programmingoneonone

LEARN EVERYTHING ABOUT PROGRAMMING

HackerRank Quadrant Queries problem solution

YASH PAL, 31 July 2024

In this HackerRank Quadrant Queries problem solution, we have given n points on a plane and each point is described by (x,y) coordinates and we need to perform some queries given by the user.

HackerRank Quadrant Queries problem solution

Topics we are covering

Toggle
  • Problem solution in Python.
  • Problem solution in Java.
  • Problem solution in C++.
  • Problem solution in C.

Problem solution in Python.

import bisect
from math import sqrt
import optparse
import sys
from random import randint as rand

_Rx = [3, 2, 1, 0]
_Ry = [1, 0, 3, 2]

def create_test(N, Q, fp):
    r = [(rand(-2, 2), rand(-2, 2)) for i in range(N)]
    print(N, file = fp)
    for ri in r:
        print('%d %d' % ri, file = fp)
    ops = [ "X", "Y", "C" ]
    queries = [(ops[rand(0, 2)], rand(1, N), rand(1, N)) for q in range(Q)]
    print(Q, file = fp)
    for op, i, j in queries:
        if i > j: 
            i, j = j, i
        print('%1s %d %d' % (op, i, j), file = fp)
    return [r, queries]
    
def quadrant(x, y):
    '''
    Return the quadrant the point r is in.
    '''
    if x > 0:
        if y > 0: return 0
        else: return 3
    else:
        if y > 0: return 1
        else: return 2
    
def getInput(f, shift = -1):
    '''
    The first line contains N, the number of points. N lines follow.
    The ith line contains xi and yi separated by a space.  The next line
    contains Q the number of queries. The next Q lines contain one query
    each, of one of the above forms.  All indices are 1 indexed.

    Return the points r and the queries q, in [r, q]
    '''
    l = f.readline().strip()
    n = int(l)
    r = []
    for i in range(n):
        l = f.readline().strip()
        x, y = l.split()
        r.append([int(x), int(y)])
    l = f.readline().strip()
    Q = int(l)
    queries = []
    for k in range(Q):
        l = f.readline().strip()
        op, i, j = l.split()
        queries.append((op, int(i) + shift, int(j) + shift))
    return [r, queries]

class QuadrantBook:
    '''
    A data structure to facilitate the processing of quadrant queries.
    '''
    def __init__(self, r, factor = 32):
        N = len(r)
        self.blocksize = int(sqrt(factor * N))
        nblocks = (N - 1) // self.blocksize + 1
        # self.inq[b][q] is the list of points in the quadrant q with indices
        # between b L and (b+1)L, where L is the blocksize.
        self.inq = [[[] for q in range(4) ] for b in range(nblocks)]
        for i, ri in enumerate(r):
            b = self.getBlock(i)
            q = quadrant(ri[0], ri[1])
            self.inq[b][q].append(i)

    def countInQuadrants( self, i, j):
        '''
        Count the number of points in each quadrant with indices between i and j,
        inclusive.
        '''
        bi = self.getBlock(i)
        bj = self.getBlock(j)
        cq = [0] * 4
        if bi == bj:
            for q, idx in enumerate(self.inq[bi]):
                ki, kj = getIndex(idx, i, j)
                cq[q] = kj - ki
            return cq
        else:
            for q in range(4):
                ni = self.inq[bi][q]
                nj = self.inq[bj][q]
                ki = bisect.bisect_left(ni, i)
                kj = bisect.bisect_right(nj, j)
                cq[q] = len(ni) - ki 
                for nb in self.inq[bi + 1: bj]:
                    cq[q] += len(nb[q])
                cq[q] += kj
            return cq

    def reflect( self, i, j, axis):
        '''
        Update the list of points in each quadrant after reflection along the
        given axis.
        '''
        if axis == "X":
            R = _Rx
            W = [(0, 3), (1, 2)]
        else:
            R = _Ry
            W = [(0, 1), (2, 3)]    
        bi = self.getBlock( i)
        bj = self.getBlock( j)
        if bi == bj:
            self.reflectInBlock( i, j, bi, R)
        else:
            ni = self.inq[bi]
            kiq = [bisect.bisect_left(idx, i) for idx in ni]
            rfxi = [ni[q][ki:] for q, ki in enumerate(kiq)]
            for q, ki in enumerate(kiq):
                ni[q] = ni[q][:ki] + rfxi[R[q]]   
            nj = self.inq[bj]
            kjq = [bisect.bisect_right( idx, j) for idx in nj]
            rfxj = [nj[q][:kj] for q, kj in enumerate(kjq)]
            for q, kj in enumerate( kjq):
                nj[q] = rfxj[R[q]] + nj[q][kj:]    
            for nb in self.inq[bi + 1: bj]:
                for w1, w2 in W:
                    nb[w1], nb[w2] = nb[w2], nb[w1]
          
    def getBlock( self, i ):
        '''
        Get the block index for point i.
        '''
        return i // self.blocksize


    def reflectInBlock(self, i, j, b, R):
        '''
        Update the list of points in each quadrant after reflection along the
        given axis, assuming that i and j are in the same block b.
        '''
        nb = self.inq[b]
        kij = [getIndex( idx, i, j) for idx in nb]
        rf = [nb[q][ki: kj] for q, (ki, kj) in enumerate(kij)]
        for q, (ki, kj) in enumerate(kij):
            nb[q] = nb[q][:ki] + rf[R[q]] + nb[q][kj:]

def getIndex( lst, i, j):
    '''
    In the sorted list, find ki such that lst[ki-1]<i<=lst[ki], and kj such
    that lst[kj]<=j<lst[kj+1]. If i<lst[0], ki=0; if j>lst[-1], kj=len(lst).
    This convention splices the list at the right places.

    @param i<=j
    '''
    ki = bisect.bisect_left(lst, i)
    kj = bisect.bisect_right(lst, j, ki)
    return [ki, kj]

def processQueries(r, queries, factor = 32):
    qbook = QuadrantBook(r, factor)
    for op, i, j in queries:
        if op.upper() == 'C':
            cq = qbook.countInQuadrants(i, j)
            print('%d %d %d %d' % tuple(cq), file = sys.stdout)
        elif op.upper() in ['X', 'Y']:
            qbook.reflect( i, j, op)


if __name__ == '__main__':
    usage = '%prog'
    opt = optparse.OptionParser(usage)
    opt.add_option('-N', type = 'int', default = 100)
    opt.add_option('-Q', type = 'int', default = 10)
    opt.add_option('-c', '--create', action = 'store_true', default = False, help = 'Create test case instead of running the query.')
    opt.add_option('-i', '--input', type='string', default = None, help = 'Input file.')
    opt.add_option('-b', '--block-factor', type = 'float', default = 32., help = 'Use sqrt(b * N) as the block size.')
    opts, args = opt.parse_args()
    if opts.create:
        r, queries = create_test(opts.N, opts.Q, sys.stdout)
    else:
        r, queries = getInput(opts.input and open(opts.input, 'r') or sys.stdin)
        processQueries(r, queries, opts.block_factor)
  

{“mode”:”full”,”isActive”:false}

Problem solution in Java.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    private static final int[] BC = new int[1<<16];
    public static void main(String[] argv) throws Exception {
        prep();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line1 = br.readLine();
        int N = Integer.parseInt(line1);
        ArrayList<String> dump = new ArrayList<String>(100000);
        int[] x = new int[N/32+1];
        int[] y = new int[N/32+1];
        long rs = System.currentTimeMillis();
        for(int i=0;i<N;i++){
            String line2 = br.readLine();
            String[] tmp2 = line2.split(" ");
            if(tmp2[0].charAt(0) != '-') x[i/32] |= 1<< i%32;
            if(tmp2[1].charAt(0) != '-') y[i/32] |= 1<< i%32;
        }
        long re = System.currentTimeMillis();
        String line3 = br.readLine();
        int Q = Integer.parseInt(line3);
        boolean wasC = false;
        int[] tmp1 = new int[N/32+1];
        int[] tmp24= new int[N/32+1];
        int[] tmp2 = new int[N/32+1];
        int[] cnt1 = new int[N/32+1];
        int[] cnt24= new int[N/32+1];
        int[] cnt2 = new int[N/32+1];
        long ws = System.currentTimeMillis();
        for(int i=0;i<Q;i++){
            String line4 = br.readLine();
            String[] tmp4 = line4.split(" ");
            int sindex = Integer.parseInt(tmp4[1]);
            int eindex = Integer.parseInt(tmp4[2]);
            int sm = (sindex-1)%32;
            int sn = (sindex-1)/32;
            int em = eindex%32;
            int en = eindex/32;
            int es = eindex-sindex+1;
            if(tmp4[0].equals("X")) {
                if(sn == en){
                    int mask = ((1<<(es))-1)<<(sm);
                    y[en] ^= mask;
                }else{
                    int mask = -1;
                    int fmask = mask<<(sm);
                    int emask = (1<<(em))-1;
                    y[sn] ^= fmask;
                    for(int j=sn+1;j<en;j++) y[j] ^= mask;
                    y[en] ^= emask;
                }
                wasC = false;
            }else if(tmp4[0].equals("Y")) {
                if(sn == en){
                    int mask = ((1<<(es))-1)<<(sm);
                    x[en] ^= mask;
                }else{
                    int mask = -1;
                    int fmask = mask<<(sm);
                    int emask = (1<<(em))-1;
                    x[sn] ^= fmask;
                    for(int j=sn+1;j<en;j++) x[j] ^= mask;
                    x[en] ^= emask;
                }
                wasC = false;
            }else{
                /*
                if(!wasC || wasC){
                    for(int j=0;j<x.length;j++) {
                        tmp1[j]  = x[j] & y[j];
                        tmp24[j] = x[j] ^ y[j];
                        tmp2[j]  = tmp24[j] & y[j];
                        cnt1[j] = bitCount(tmp1[j]);
                        cnt24[j]= bitCount(tmp24[j]);
                        cnt2[j] = bitCount(tmp2[j]);
                    }
                }
                */
                int maskes = ((1<<(es))-1)<<(sm);
                int maskall = -1;
                int fmask = maskall<<(sm);
                int emask = (1<<(em))-1;
                // 1st quadrant x bit: 1, y bit: 1 (x & y)
                int c1 = 0;
                if(sn == en){
                    c1 += bitCount(x[en] & y[en] & maskes);
                }else{
                    c1 += bitCount(x[sn] & y[sn] & fmask);
                    for(int j=sn+1;j<en;j++) c1 += bitCount(x[j] & y[j]);
                    c1 += bitCount(x[en] & y[en] & emask);
                }
                // 2nd quadrant x bit: 0, y bit: 1
                // 4th quadrant x bit: 1, y bit: 0
                // x xor y = c2 + c4
                // (x xor y) & y = c2
                int c24 = 0;
                int c2 = 0;
                if(sn == en){
                    int t2 = (x[en] ^ y[en]) & maskes;
                    c24 += bitCount(t2);
                    c2 += bitCount(t2 & y[en]);
                }else{
                    int t2 = (x[sn] ^ y[sn]) & fmask;
                    c24 += bitCount(t2);
                    c2 += bitCount(t2 & y[sn]);
                    for(int j=sn+1;j<en;j++) {
                        t2 = x[j] ^ y[j];
                        c24 += bitCount(t2);
                        c2 += bitCount(t2 & y[j]);
                    }
                    t2 = (x[en] ^ y[en]) & emask;
                    c24 += bitCount(t2);
                    c2 += bitCount(t2 & y[en]);
                }
                int c4 = c24 - c2;
                // 3rd quadrant x bit: 0, y bit: 0 (total - c1 - c2 - c4)
                int c3 = eindex - sindex + 1 - c1 - c2 - c4;
                dump.add(c1+" "+c2+" "+c3+" "+c4);
                //System.out.println(c1+" "+c2+" "+c3+" "+c4);
                wasC = true;
            }
        }
        long we = System.currentTimeMillis();
        for(int i=0;i<dump.size();i++) System.out.println(dump.get(i));
        br.close();
        //System.out.println("R:"+(re-rs));
        //System.out.println("W:"+(we-ws));
    }
    private static void prep() {
        int max = 1<<16;
        int step1 = 1<<8;
        for(int i=0;i<step1;i++) BC[i] = Integer.bitCount(i);
        for(int i=step1;i<max;i++){
            BC[i] = BC[i&0xFF] + BC[(i>>8)&0xFF];
        }
    }
    
    private static int bitCount(int i){
        return BC[i&0xFFFF] + BC[(i>>16)&0xFFFF];
    }
}

Problem solution in C++.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxN = 100000;

const int R[4][4] =
{
  {0, 1, 2, 3},
  {3, 2, 1, 0},
  {1, 0, 3, 2},
  {2, 3, 0, 1}
};

int N;
int px[maxN], py[maxN];

int Q;

struct Node
{
  int l, r;
  int nq[4]; // number of points in each quadrant, applying reflect mask on children nodes (exclude self)
  int mask; // reflect mask X(0) Y(1)
  Node *lt, *rt;
};

Node *root;

Node *bst_build (int l, int r)
{
  Node *p = (Node *)malloc(sizeof(Node));
  p->l = l, p->r = r;
  memset(p->nq, 0, sizeof(p->nq));
  p->mask = 0;
  p->lt = p->rt = NULL;

  if (r - l > 1)
  {
    int m = (l + r) / 2;
    Node *lt = bst_build(l, m);
    Node *rt = bst_build(m, r);
    p->lt = lt;
    p->rt = rt;
  }

  if (r - l > 1)
  {
    for (int i = 0; i < 4; ++i)
      p->nq[i] = p->lt->nq[i] + p->rt->nq[i];
  }
  else
  {
    int q;
    if (px[l] > 0)
      if (py[l] > 0)
        q = 0;
      else
        q = 3;
    else
      if (py[l] > 0)
        q = 1;
      else
        q = 2;
    p->nq[q] = 1;
  }

  return p;
}

void bst_mask (int ax, Node *p, int l, int r)
{
  if (p->l == l && p->r == r)
  {
    p->mask ^= 1 << ax;
    return;
  }

  if (l < p->lt->r)
    bst_mask(ax, p->lt, l, min(r, p->lt->r));
  if (r > p->rt->l)
    bst_mask(ax, p->rt, max(l, p->rt->l), r);
  
  for (int i = 0; i < 4; ++i)
  {
    p->nq[i] = p->lt->nq[R[p->lt->mask][i]] + p->rt->nq[R[p->rt->mask][i]];
  }
}

void bst_query (Node *p, int l, int r, int mask, int res[4])
{
  mask ^= p->mask;
  
  if (p->l == l && p->r == r)
  {
    for (int i = 0; i < 4; ++i)
    {
      res[i] += p->nq[R[mask][i]];
    }
    return;
  }

  if (l < p->lt->r)
    bst_query(p->lt, l, min(r, p->lt->r), mask, res);
  if (r > p->rt->l)
    bst_query(p->rt, max(l, p->rt->l), r, mask, res);
}

int main ()
{
  scanf("%d", &N);
  for (int i = 0; i < N; ++i)
    scanf("%d%d", &px[i], &py[i]);

  root = bst_build(0, N);

  scanf("%d", &Q);
  for (int i = 0; i < Q; ++i)
  {
    char c;
    int l, r;
    scanf(" %c%d%d", &c, &l, &r);
    --l;
    switch (c)
    {
      case 'X':
      {
        bst_mask(0, root, l, r);
        break;
      }
      case 'Y':
      {
        bst_mask(1, root, l, r);
        break;
      }
      case 'C':
      {
        int res[4];
        memset(res, 0, sizeof(res));
        bst_query(root, l, r, 0, res);
        printf("%d %d %d %dn", res[0], res[1], res[2], res[3]);
        break;
      }
    }
  }
}

{“mode”:”full”,”isActive”:false}

Problem solution in C.

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
 
enum {
  XAXIS = 0,
  YAXIS = 1
};
 

 
typedef struct node node;
struct node {
  int count;
  node *left, *right;
};
 
node *pool;
int nnodes, npool;
 
typedef struct tree tree;
struct tree {
  node *root[4];
  int nlevels;
};
 
node *newnode() {
  assert(nnodes < npool);
  return &pool[nnodes++];
}
 
node *mktree(int level) {
  node *np;
 
  np = newnode();
  if (level == 0)
    return np;
 
  np->left = mktree(level-1);
  np->right = mktree(level-1);
  return np;
}
 
tree *inittree(int n) {
  tree *tp;
  int i;
 
  tp = (tree *) malloc(sizeof(*tp));
  if (tp == NULL)
    exit(1);
  
  tp->nlevels = 0;
  while ((1 << tp->nlevels) < n)
    tp->nlevels++;
 
  npool = 4 * (1 << (tp->nlevels+1));
  pool = calloc(npool, sizeof(node));
  if (pool == NULL)
    exit(1);
 
  for (i = 0; i < 4; i++)
    tp->root[i] = mktree(tp->nlevels);
 
  return tp;
}
 
void _add(node *np, int lvl, int idx, int x) {
  int lt, rt, mid;
 
  np->count++;
 
  if (lvl == 0)
    return;
 
  lt = (1<<lvl) * idx;
  mid = lt + (1<<(lvl-1));
  rt = lt + (1<<lvl) - 1;
 
  assert(lt <= x && x <= rt);
  if (x < mid)
    _add(np->left, lvl-1, 2*idx, x);
  else
    _add(np->right, lvl-1, 2*idx + 1, x);
}
 
/* Add a value at x in quadrant q. */
void add(tree *tp, int x, int q) {
  _add(tp->root[q], tp->nlevels, 0, x);
}
 
int _count(node *np, int lvl, int idx, int l, int r) {
  int lt, rt;
 
  lt = (1<<lvl) * idx;
  rt = lt + (1<<lvl) - 1;
 
  /* Out of bounds. */
  if (r < lt) return 0;
  if (l > rt) return 0;
 
  /* Whole range. */
  if (l <= lt && rt <= r)
    return np->count;
 
  /* Left and right children. */
  return _count(np->left, lvl-1, 2*idx, l, r) +
    _count(np->right, lvl-1, 2*idx + 1, l, r);
}
 
/* count: print # in each quadrant from l -> r inclusive. */
void count(tree *tp, int l, int r) {
  int q[4];
  int i;
 
  for (i = 0; i < 4; i++)
    q[i] = _count(tp->root[i], tp->nlevels, 0, l, r);
  printf("%d %d %d %dn", q[0], q[1], q[2], q[3]);
}
 
void _flip(node **np, int lvl, int idx, int l, int r, int typ) {
  int lt, rt, i;
  node *tmp, *lp[4], *rp[4];
 
  lt = (1<<lvl) * idx;
  rt = lt + (1<<lvl) - 1;
 
  /* Out of bounds. */
  if (r < lt) return;
  if (l > rt) return;
 
  /* Whole range. */
  if (l <= lt && rt <= r) {
    assert(typ == XAXIS || typ == YAXIS);
    switch (typ) {
    case XAXIS:
      tmp = np[0]; np[0] = np[3]; np[3] = tmp;
      tmp = np[1]; np[1] = np[2]; np[2] = tmp;
      break;
    case YAXIS:
      tmp = np[0]; np[0] = np[1]; np[1] = tmp;
      tmp = np[2]; np[2] = np[3]; np[3] = tmp;
      break;
    default:
      assert(0);
      break;
    }
    return;
  }
 
  assert(lvl > 0);
 
  /* Left and right children. */
  for (i = 0; i < 4; i++) {
    lp[i] = np[i]->left;
    rp[i] = np[i]->right;
  }
 
  _flip(lp, lvl-1, 2*idx, l, r, typ);
  _flip(rp, lvl-1, 2*idx + 1, l, r, typ);
 
  for (i = 0; i < 4; i++) {
    np[i]->left = lp[i];
    np[i]->right = rp[i];
    np[i]->count = lp[i]->count + rp[i]->count;
  }
}
 
/* flip: flip points about axis. */
void flip(tree *tp, int l, int r, int typ) {
  _flip(tp->root, tp->nlevels, 0, l, r, typ);
}
 
int quadrant(int x, int y) {
  if (x > 0 && y > 0) return 0;
  if (x < 0 && y > 0) return 1;
  if (x < 0 && y < 0) return 2;
  if (x > 0 && y < 0) return 3;
  /* shouldn't get here */
  assert(0);
  return -1;
}
 
int main() {
  int i, x, y, a, b, npoints, nqueries;
  char query;
  tree *tp;
 
  if (scanf(" %d", &npoints) != 1)
    return 1;
  tp = inittree(npoints);
  for (i = 0; i < npoints; i++) {
    if (scanf(" %d %d", &x, &y) != 2)
      return 1;
    if (x == 0 || y == 0)
      return 1;
    add(tp, i, quadrant(x, y));
  }
 
  if (scanf(" %d", &nqueries) != 1)
    return 1;
  for (i = 0; i < nqueries; i++) {
    if (scanf(" %c %d %d", &query, &a, &b) != 3)
      return 1;
    switch (query) {
    case 'C':
      count(tp, a-1, b-1);
      break;
    case 'X':
      flip(tp, a-1, b-1, XAXIS);
      break;
    case 'Y':
      flip(tp, a-1, b-1, YAXIS);
      break;
    default:
      return 1;
    }
  }
  
  return 0;
}

{“mode”:”full”,”isActive”:false}

Algorithms coding problems solutions

Post navigation

Previous post
Next post
  • Automating Image Format Conversion with Python: A Complete Guide
  • HackerRank Separate the Numbers solution
  • How AI Is Revolutionizing Personalized Learning in Schools
  • GTA 5 is the Game of the Year for 2024 and 2025
  • Hackerrank Day 5 loops 30 days of code solution
How to download udemy paid courses for free

Pages

  • About US
  • Contact US
  • Privacy Policy

Programing Practice

  • C Programs
  • java Programs

HackerRank Solutions

  • C
  • C++
  • Java
  • Python
  • Algorithm

Other

  • Leetcode Solutions
  • Interview Preparation

Programming Tutorials

  • DSA
  • C

CS Subjects

  • Digital Communication
  • Human Values
  • Internet Of Things
  • YouTube
  • LinkedIn
  • Facebook
  • Pinterest
  • Instagram
©2025 Programmingoneonone | WordPress Theme by SuperbThemes