Tuesday, 1 March 2016

******Benny and Queries( FIND MAXIMUM OF X XOR ANY NO IN RANGE L TO R ) SUCH THAT X XOR NO IS HIGHEST

Benny and Queries
Benny and Queries

Probably, you have already read some problems but you still have not met any problems with queries on segments. Therefore Benny wants to fix it.
She gives you an array A of N elements. And then you have to answer Q queries.
Each query consists of three integers LRX. Your task is to find such Ai, that L ≤ i ≤ R and Ai xor X is maximal. For each query output the maximum of Ai xor X.
Input format
The first line contains two integers N and Q. The next line contains N integers Ai. The next Q lines contain three integersLRX.
Output format
For each query output the maximum of Ai xor X in a single line.
Constraints
  • 1 ≤ N, Q ≤ 5 * 105
  • 0 ≤ Ai < 220
  • 1 ≤ L ≤ R ≤ N
  • 0 ≤ X < 220
  • 1 ≤ N, Q ≤ 3 * 103 holds for test cases worth 15% of the problem's score.
  • 1 ≤ N, Q ≤ 105 holds for test cases worth 60% of the pro
  • 1 ≤ N, Q ≤ 105 holds for test cases worth 60% of the problem's score.
  • INPUT
  • 5 3
    1 7 3 8 2
    1 5 10
    3 4 6
    2 5 8
  • OUTPUT
  • 13
    14
    15
  • ----------------------------------------EDITORIAL-------------------------------------------------------------------------
  •   ON EACH NODE OF TRIE KEEP A SET BUT IT WILL GIVE TLE , BUT AS WE ARE INSERTING INDEX  IN INCREASING ORDER OF INDEX SO WE CAN   USE VECTOR ON EACH NODE ALSO ....
  • How to solve this problem if l = 1 and r = n in all queries? We can consider every number as binary string of length 20. For example, 47 equals 00000000000000101111. Let's build a trie on all this strings. You can read about trie here orhere. How can we answer a query when? Let's find the same binary string of X. Now the largest bit of X xor Ai will be 1 iff the largest bit of X differs from the largest bit of Ai. So we can check if there exist an edge from the root with label equals to opposite of the largest bit of X. Then we can try next bit and so on.
    Now we have queries with l and r. Let's keep in every node of the trie a sorted array of indices of all number that passes through this node. When we want to check if there exist a number with given prefix and index in range [l, r] we need to binary search it in sorted array of appropriate node.
    Complexity of such solution will be O(n log2n).
    Also this problem can be solved with segment tree of tries or persistent trie.
    You can check solutions by setter and tester for implementation details.


#include<iostream>
using namespace std;
#include<bits/stdc++.h>
void calc(int val[])
 {
  val[0]=1;
   for(int i=1;i<=31;i++)
   {
    val[i]=val[i-1]*2;
  }
 //  cout<<" generation done "<<endl;
  return;
 }
class node
{
public:
 node * ll,*rr;
 vector<int> s;
 node()
  {
  ll=NULL;
  rr=NULL;
 
}
};

int join(node * head,int val[],int num,int index)
 {
     node *var=head;    
    for(int i=21;i>=0;i--)
     {
      if(num&val[i])
       {
        if(head->rr!=NULL)
         {
          // cout<<" join existing "<<endl;
          head=head->rr;
         // cout<<" ins "<<index<<endl;
          head->s.push_back(index);
}
else
{
// cout<<" create"<<endl;
head->rr= new node();
head=head->rr;
// cout<<" ins "<<index<<endl;
head->s.push_back(index);
}
 
  }
  
  
 else
       {
        // cout<<" off "<<endl;
       // int f=0;
        if(head->ll!=NULL)
         {
          //  cout<<"join "<<endl;
          head=head->ll;
         // cout<<" ins "<<index<<endl;
          head->s.push_back(index);
         
}
else
{
// cout<<" create "<<endl;
head->ll= new node();
head=head->ll;
// cout<<" ins "<<index<<endl;
head->s.push_back(index);
}
 
  }
}
 }
 int find(node * head,int v[],int l,int r,int num)
  {
   //cout<<" find for "<<num<<" in "<<l<<" "<<r<<endl;
   node *var=head;
   
   int ans=0;
   
    for(int i=21;i>=0;i--)
     {
     
      if(!(num&v[i]))
       {
         //cout<<" at index "<<i<<" need "<<1<<endl;
          int f=0;
        if(head->rr!=NULL)
         {
           var=head->rr;
          vector<int>:: iterator it1,it2;
          it1=lower_bound(var->s.begin(),var->s.end(),l);
          it2=lower_bound(var->s.begin(),var->s.end(),r+1);
         // if(it!=var->s.end()  && *it1>r) it1--;
          it2--;
          if(it1!=var->s.end()   && *it1<=r  && *it1>=l && *it2<=r && *it2>=l)
          {
          //  cout<<" yah fine "<<endl;
          ans=ans|v[i];
          // cout<<ans<<endl;
          head=head->rr;
          f=1;
 }
         
}
if(f==0)
 {
  // cout<<" no "<<endl;
  head=head->ll;
 }
  }
  
  
else
       {
       // cout<<" at index "<<i<<" need "<<0<<endl;
          int f=0;
        if(head->ll!=NULL)
         {
         var=head->ll;
          vector<int>:: iterator it1,it2;
          it1=lower_bound(var->s.begin(),var->s.end(),l);
          it2=lower_bound(var->s.begin(),var->s.end(),r+1);
          it2--;
         
          if(it1!=var->s.end()   && *it1<=r  && *it1>=l && *it2<=r && *it2>=l)
          {
          // cout<<" yah fine "<<endl;
          ans=ans|v[i];
          // cout<<ans<<endl;
          head=head->ll;
          f=1;
 }
         
}
if(f==0)
 {
  //cout<<" no  "<<endl;
  head=head->rr;
 }
  }
  
  
}
 
return ans;
  }
 int main()
  {
  int n,q;
   cin>>n>>q;
    int arr[n+10];
    int val[100];
    calc(val);
    
     for(int i=0;i<n;i++)
      {
       scanf("%d",&arr[i]);
  }
  node *head1=new node();
 
  for(int  i=0;i<n;i++)
   {
      join(head1,val,arr[i],i+1);
}
for(int i=0;i<q;i++)
 {
  int px,py,x;
  scanf("%d %d %d",&px,&py,&x);
  int ans=find(head1,val,px,py,x);
  cout<<ans<<endl;
 }
   
  }