Tuesday, 15 September 2015

Given an array of n non-negative integers: A1A2, …, AN. Your mission is finding a pair of integers Au,Av (1 ≤ u < v ≤ N) such that (Au and Av) is as large as possible.
And is a bit-wise operation which is corresponding to & in C++ and Java.

Input

The first line of the input contains a single integer N. The ith line in the next N lines contains the Ai.

Output

Contains a single integer which is the largest value of Au and Av where 1 ≤ u < v ≤ N.

Constraints

50 points:
  • 2 ≤ N ≤ 5000
  • 0 ≤ Ai ≤ 109
50 points:
  • 2 ≤ N ≤ 3 × 105
  • 0 ≤ Ai ≤ 109

Example

Input:
4
2
4
8
10

Output:
8


Explanation

  • 2 and 4 = 0
  • 2 and 8 = 0
  • 2 and 10 = 2
  • 4 and 8 = 0
  • 4 and 10 = 0
  • 8 and 10 = 8

When we are ANDing two numbers, we would like to have a 1 at the most significant bit(MSB). So, first we'll try to get a 1 at MSB. Now, suppose we denote A[i]=b_in,b_in-1...b_i0, where b_i's are the bits that could be 1 or 0.
Let's say S be the set of A[i] whose b_in is 1 and S' be the set of A[i] whose b_in is 0. If size of S ≥ 2 we are sure that our answer will be maximum if we chose a pair of numbers from S, because n'th bit of their AND will be 1 for sure. So, we know our answer lies in S.
However, if size of S is less than 2, we can never have n'th bit 1 in our answer. So, we'll have to continue with n'th bit as 0. Note that our answer will now be in S'.
Now, we know our answer is in S or S' and we also know n'th bit of our answer. So, our new subproblem is to find (n-1)'th bit of our answer using numbers in S or S'. We can write a recursive code for this. What will be the complexity? For each of the n bits, we'll traverse whole array to sort according to their bits. So O(n*N). We will be keeping n=30, because A[i] ≤ 109.
n=input()
arr=[]
flag[n]={}
for i=0 to n-1:
    arr[i]=input()
print foo(30)

def foo(level):  //this function will find the level'th bit
                //and accordingly return answer
    if level==-1:  // we already have solved for all bits. return 0 from here
        return 0
    Scount=0  // stores the size of set S
    ans=0 // the answer in decimal form
    for i=0 to n-1:
        if flag[i]==0:  // flag[i]=0 means arr[i] is available for us to use
            if (arr[i]&(1<<level)): // level'th bit of arr[i] is 1
                Scount++
    if Scount>=2: // our answer's level'th bit will be 1
        ans += (1<<level)
        // but we also have to set the flag of unavailable numbers
        for i=0 to n-1:
            if (arr[i]&(1<<level))==0:  // level'th bit is 0, set the flag
                flag[i]=1
    return ans+foo(level-1);  // return the current answer + answer for the next bit

code goes here


#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define mp make_pair
list<int> sup[100010];
long long int val[100010];
bool visited[100010];
long long int arr[100010];
int top=0;
long long int sttime[100010];
long long int endtime[100010];
long long int vis=0;
long long int  t[1000100];

void build(int node, int a, int b)
{
 if(a>b) return;
 if (a==b)
 {
  t[node]=arr[a];
  return;
 }
 
 build(node*2, a, (a+b)/2);
 build(node*2+1,(a+b)/2+1,b);
 
 t[node]=t[node*2]+t[node*2+1];
}

long long int  query(int node, int a, int b, int i, int j)
{
 if(a>b||a>j||b<i) return 0;
 
 if (a>=i && b<=j) return t[node];
 
 int q1=query(node*2, a, (a+b)/2, i, j);
 int q2=query(node*2+1, (a+b)/2+1, b, i, j);
 
 return q1+q2;
}

void update(int node, int a, int b, int i, int j, long long int inc)
{
 if(a>b) return;
 
 if(a>b||a>j||b<i) return;
 
 if (a>=i && b<=j)
 {
  t[node]=inc;
  
  return;
 }
 
 update(node*2, a, (a+b)/2, i, j, inc);
 update(node*2+1, (a+b)/2+1, b,i, j, inc);
 t[node] = t[node*2] + t[node*2+1];
}
void dfs(int st)
{
 //cout<<"called "<<st<<" tm "<<vis<<endl;
     list<int> ::iterator it;
     arr[vis]=val[st];  
     sttime[st]=vis;
     visited[st]=1;
     for( it=sup[st].begin();it!=sup[st].end();it++)
     {
      if(visited[*it]==0)
      {
            vis++;
     visited[*it]=1;  
     dfs(*it);
     
    }
     }
   //  cout<<"enfing "<<st<<" with "<<vis<<endl;
     endtime[st]=vis;
}
int main()
{
 int n;
 cin>>n;
 int q;
 cin>>q;
 for(int i=0;i<n;i++)
 {
  scanf("%d",&val[i]);
 }
 
 for(int i=0;i<n-1;i++)
 {
  int a,b;
  scanf("%d %d",&a,&b);
  a=a-1;
  b=b-1;
  //cout<<" a and b "<<a<<" "<<b<<endl;
  sup[a].push_back(b);
  sup[b].push_back(a);
 }
// cout<<sup[0].size()<<endl;
// cout<<"size "<<endl;
  visited[0]=1;
 dfs(0);

 //cout<<"done "<<endl;
/* for(int i=0;i<n;i++)
 {
  cout<<arr[i]<<" ";
 }
 cout<<endl;
 for(int i=0;i<n;i++)
 {
  cout<<sttime[i]<<" ";
 }
 cout<<endl;
 for(int i=0;i<n;i++)
 {
  cout<<endtime[i]<<" ";
 }
 cout<<endl;*/
 
 build(1,0,n-1);
 //cout<<endl;
 char str[5];
 while(q--)
 {
  int node;long long int  val;
  scanf("%s",str);
  if(str[0]=='Q')
  {
   cin>>val;
   val--;
   int qs,qe;
   qs=sttime[val];
   qe=endtime[val];
  // cout<<"query "<<qs<<" "<<qe<<endl;
   long long int ans=query(1,0,n-1,qs,qe);
    cout<<ans<<endl;
  }
  else
  {
      cin>>node>>val;
      node--;
      
      int upl=sttime[node];
      int upu=sttime[node];
      update(1,0,n-1,upl,upu,val);
  }
 }
 return 0;
}

No comments:

Post a Comment