I have almost solved this quadrant queries problem of Interviewstreet using segment trees with lazy propagation but I’m still getting wrong answer so I need help in my code.
This is the question:
Quadrant Queries
There are N points in the plane. The ith point has coordinates (xi, yi). Perform the following queries:
- Reflect all points between point i and j both including along the X axis. This query is represented as
X i j - Reflect all points between point i and j both including along the Y axis. This query is represented as
Y i j - Count how many points between point i and j both including lie in each of the 4 quadrants. This query is represented as
C i j
Input:
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.
Output:
Output one line for each query of the type C i j. The corresponding line contains 4 integers; the number of points having indices in the range [i..j] in the 1st,2nd,3rd and 4th quadrants respectively.
Constraints:
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
Sample Input:
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
Sample Output:
1 1 1 1
1 1 0 0
0 2 0 1
Explanation:
When a query says X i j, it means that take all the points between indices i and j both including and reflect those points along the X axis. The i and j here have nothing to do with the co-ordinates of the points. They are the indices. i refers to point i and j refers to point j
C 1 4 asks you to ‘Consider the set of points having index in {1,2,3,4}. Amongst those points, how many of them lie in the 1st, 2nd, 3rd and 4th quads respectively?’ The answer to this is clearly 1 1 1 1.
Next we reflect the points between indices ‘2 4’ along the X axis. So the new coordinates are :
1 1
-1 -1
-1 1
1 1
Now C 3 4 is ‘Consider the set of points having index in {3,4}. Amongst those points, how many of them lie in the 1st, 2nd, 3rd and 4th quads respectively?’ Point 3 lies in quadrant 2 and point 4 lies in quadrant 1. So the answer is 1 1 0 0.
Current Code
Here is my solution in 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 ;
}
If I understand your algorithm correctly, you are using the L array to keep track of whether a a range of points needs to be flipped or not, but deferring the actual flip until it becomes necessary.
In this case, I think there might be a problem with the lines:
Suppose L[node][0] was 1, and L[2*node+1][0] was already 1. This means that some previous step wanted to flip the nodes at 2*node+1, and then this step also wants to flip these nodes. These flips should cancel out and L[2*node+1][0] should become zero.
I think you should change these lines to use xor so that a double flip will cancel:
(Or perhaps I have misunderstood the approach!)