Tuesday, 6 December 2016

checking existance of a string in a dictonarty and adding a word in dictonary

// code for checking existance of a string in a dictonarty and adding a word in dictonary
#include<bits/stdc++.h>
using namespace std;
class node
{
public :
node *pointers[26];
int end;

node()
{
for(int i=0;i<27;i++)
{
pointers[i]=NULL;
}
end=0;
}

};
void add(node *curr,string s)
 {
  int len=s.length();
  for(int i=0;i<len;i++)
    {
      int  idx=s[i]-'a';
       if(curr->pointers[idx]!=NULL)
         {
  curr=curr->pointers[idx];
     
 }
 else
 {
  curr->pointers[idx]=new node();
 curr=curr->pointers[idx];
 }
    if(i==len-1) curr->end+=1;
  }
 }

bool check(node * curr,string s)
 {
  int len=s.length();
  for(int i=0;i<len;i++)
    {
      int  idx=s[i]-'a';
    if(curr->pointers[idx]!=NULL)
         {
  curr=curr->pointers[idx];
     
 }
 else
 {
   return false;
 }
 if(i==len-1) return (curr->end >=1);
   
  }
  return true;
 }

int main()
 {
  cout<<" give the number of opetrations "<<endl;
  node * root =new node();
  int    count =0;
  cin>>count;
  while(count)
   {
     int type;
       cout<<" for adding a string press 0 \n for checking press 1  "<<endl;
      cin>>type;
   
      if(type==0)// add;
          {
   string s;
cin>>s;  
 if(!check(root,s))
 {
  add(root,s);
 }
 else
 {
  cout<<"already exists :)"<<endl;
 }
   }
 
   else if(type==1)
   {
    string ss;
    cin>>ss;
    if(check(root,ss))
     {
      cout<<" existes "<<endl;
 }
 else
 {
  cout<<" not exists "<<endl;
 }
}
else
{
cout<<"invalid type "<<endl;
}
 
 }
 }

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;
 }
   
  } 

Sunday, 1 November 2015

Bank and vulnerable passwords

Bank and vulnerable passwords 



All submissions for this problem are available.

There is a bank which gives their customers a password 'only' for transactions(there is no username) via ATM. Also the ATM does not have any enter key, it automatically logs you into your account as soon as you enter the right password. There is a huge problem in such type of system,i.e., suppose that if two people A and B have “aadil” and “aadilahmad” as their passwords respectively, so whenever B will try to login, the machine will automatically login B into A’s account.
Input:

First line of the input contains an integer N,the number of users in Bank. Next N lines contains strings which are passwords of the users. Tell if the bank is vulnerable or non-vulnerable.
Output:

Print "vulnerable" if the bank is vulnerable or "non vulnerable" if the bank is not vulnerable.
Program constraints - 

N <= 10^5

All passwords consists of lower case english alphabets

1<=length of password<=50
Sample Input - 

2

likemeifyoucan

likeme
Sample Output - 

vulnerable

--------------------------------------------------------------editorial------------------------------------------------------------------------------

DIFFICULTY:

EASY-MEDIUM

PREREQUISITES:

Trie

PROBLEM:

Problem: Given a list of passwords (word) you need to tell whether any word is the prefix of any other word in the list.

EXPLANATION:

First of all I would like to enlighten that some of the contestents have solved the problem by just sorting them and finding the substring due to weak test cases. But the problem was intended to be solved using the data structure trie. You are given a list of words; you need to find if any word is the prefix of another word in the list. You can do so by inserting each given passwords in the trie and simultaneously checking if insertion of the password makes conflict with the condition, if so then print “vulnerable” else print “non vulnerable”. Remember to scan all the words even if the conflict occurs in between.

--------------------------------------------------code-----------------------------------------------------------------------
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<iostream>
  4. using namespace std;
  5. struct node
  6. {
  7. int word_count;
  8. struct node * has[26];
  9. bool ispre[26];
  10. };
  11. int exist=0;
  12. node* init()
  13. {
  14. node *node1=new node;
  15. node1->word_count=0;
  16. for(int i=0;i<26;i++){
  17. node1->has[i]=NULL;
  18. node1->ispre[i]=false;
  19. //cout<<"here"<<endl;}
  20. }
  21. return node1;
  22. }
  23. node *root;
  24. void build(char arr[])
  25. {
  26. node *present=root;
  27. int len=strlen(arr);
  28. // cout <<arr<<endl;
  29. for(int i=0;i<len;i++)
  30. {
  31. // cout<<"building "<<endl;
  32. int flag=0;
  33. if(present->has[arr[i]-'a']==NULL)
  34. {
  35. // cout<<" creating "<<arr[i]<<endl;
  36. flag=1;
  37. ////cout<<"making"<<endl;
  38. present->has[arr[i]-'a']=init();
  39. }
  40. if(present->ispre[arr[i]-'a']==true)
  41. {
  42. exist=1;
  43. // cout<<"herer "<<endl;
  44. }
  45.  
  46. if(i==len-1)
  47. {
  48. // cout<<"word formed with "<<arr[i]<<endl;
  49. present->ispre[arr[i]-'a']=true;
  50. }present=present->has[arr[i]-'a'];
  51. if(i==len-1 && flag==0)
  52. {
  53. exist=1;
  54. }
  55. }
  56. }
  57. int main()
  58. {
  59. int t;
  60. cin>>t;
  61. node *node1=init();
  62. root=node1;
  63. while(t--)
  64. {
  65. char arr[100000];
  66. cin>>arr;
  67. build(arr);
  68. }
  69. if(exist==1)
  70. {
  71. cout<<"vulnerable"<<endl;
  72. }
  73. else
  74. cout<<"non vulnerable"<<endl;
  75. }

**Nikitosh and xor

Nikitosh and xor 



Nikitosh the painter has a 1-indexed array A of N elements. He wants to find the maximum value of expression 

(A[l1] ⊕ A[l1 + 1] ⊕ ... ⊕ A[r1]) + (A[l2] ⊕ A[l2 + 1] ⊕ ... ⊕ A[r2]) where 1 ≤ l1 ≤ r1 < l2 ≤ r2 ≤ N.

Here, x ⊕ y means the bitwise XOR of x and y.
Because Nikitosh is a painter and not a mathematician, you need to help him in this task.

Input

The first line contains one integer N, denoting the number of elements in the array.
The second line contains N space-separated integers, denoting A1A2, ... , AN.

Output

Output a single integer denoting the maximum possible value of the given expression.

Constraints

  • 2 ≤ N ≤ 4*105
  • 0 ≤ Ai ≤ 109

Subtasks

  • Subtask 1 (40 points) : 2 ≤ N ≤ 104
  • Subtask 2 (60 points) : Original constraints

Example

Input:
5
1 2 3 1 2

Output:
6

Explanation

Choose (l1r1l2r2) = (1, 2, 3, 3) or (1, 2, 4, 5) or (3, 3, 4, 5).

----------------------------------------------------------------------editorail------------------------------------------------------------------------------

IFFICULTY:

Medium

PREREQUISITES:

Tries, Properties of Bitwise XOR

PROBLEM:

Given is an array A containing numbers in the range 0 to 109. We have to find l1r1l2 and r2 (l1r1<l2r2) such that (A[l1]A[l1+1]A[r1]) + (A[l2]A[l2+1]A[r2]) is maximised. Here xyrefers to Bitwise XOR of x and y.

EXPLANATION:

Subtask 1
Let's start off by thinking of the simplest algorithm that we can. We we will then optimise it step by step by making certain observations.
So, the simplest thing to do is to implement what the problem says. We can run four loops, one each for l1r1l2 and r2. This gives us an O(N4) algorithm which will exceed the time limit for all the subtasks.
How can we optimise this? Let's make an observation. If we know for each i = 1 to N, the maximum value we can get for (A[l1]A[l1+1]A[r1]) and (A[l2]A[l2+1]A[r2]) such that r1i and i<l2, then we can tell the answer in O(N) by simply taking the maximum of the sum of the two terms over all i.
What remains now is to calculate efficiently for each i the max (A[l1]A[l1+1]A[r1]) and (A[l2]A[l2+1]A[r2]) such that r1i and i<l2. Let's call the two terms lbest[i] and rbest[i]respectively. For calculating lbest[i], we iterate from j = i to 1 and find the j such that val = (A[j]A[j+1]A[i]) is maximised. Then, lbest[i] = max(lbest[i1],val). Similarly, we can fill the array rbest.
Calculating the arrays lbest and rbest require O(N2) time. After that, the answer can be computed in O(N). For this subtask, an O(N2) solution will pass.
Subtask 2
We need to somehow speed up the calculation of arrays lbest and rbest. Up till now, we haven't utilised any property of XOR operation in our solution. Let's try to optimise our algorithm using the following property:
Let cumul[i] = (A[1]A[2]A[i]).
Then for some jicumul[j1]cumul[i] = (A[j]A[j+1]A[i]).
The proof behind this is left to the reader as a simple exercise.
We can now say that lbest[i] = max(lbest[i1],val) where val = maximum of (cumul[j1]cumul[i]) for j = 1 to i.
Calculating lbest this way still takes O(N2). For i = 1 to N, we need to somehow optimise finding the index j such that (cumul[j1]cumul[i]) is maximum. If we can do it in O(logA[i]), then we can compute the array lbest(and analogously, rbest too) in O(NlogAmax).
We can use Tries to get the required complexity. We will keep a trie which holds the binary representation of elements in the array cumul. While processing for i from 1 to N, we will first use the trie to get the value which is maximum of (cumul[j1]cumul[i]) for 1ji, and then insert cumul[i] into the trie. This will allow us to calculate lbest in the required complexity. Similarly, we can calculate rbest also.
Inserting into a trie is a standard operation. Let us look at how we do the other operation, i.e., for a value x, finding the value y in the trie such that xy is maximised. Since, the trie stores binary representations of numbers, we first convert x to its binary representation. Then, we can go down the trie and for each bit in the representation of x, we try to find whether bit of opposite value exists or not. It is easy to see why we seek opposite; because 11 and 000 while 01 = 1.

COMPLEXITY:

--------------------------------------------------------editorial----------------------------------------------------------------------------------
  1. #include<iostream>
  2. using namespace std;
  3. #include<bits/stdc++.h>
  4. void calc(int val[])
  5. {
  6. val[0]=1;
  7. for(int i=1;i<=31;i++)
  8. {
  9. val[i]=val[i-1]*2;
  10. }
  11. // cout<<" generation done "<<endl;
  12. return;
  13. }
  14. class node
  15. {
  16. public:
  17. node * ll,*rr;
  18. node()
  19. {
  20. ll=NULL;
  21. rr=NULL;
  22. }
  23. };
  24.  
  25. int join(node * head,int val[],int num)
  26. {
  27. node *var=head;
  28. int ans=0;
  29. for(int i=29;i>=0;i--)
  30. {
  31. //cout<<" insert "<<num<< " i is "<<i<<endl;
  32. if(num&val[i])
  33. {
  34. if(head->rr!=NULL)
  35. {
  36. head=head->rr;
  37. }
  38. else
  39. {
  40. head->rr= new node();
  41. head=head->rr;
  42. }
  43. if(var->ll!=NULL)
  44. {
  45. var=var->ll;
  46. ans+=val[i];
  47. }
  48. else
  49. {
  50. var=var->rr;
  51. }
  52. }
  53. else
  54. {
  55. // cout<<" here "<<endl;
  56. if(head->ll!=NULL)
  57. {
  58. // cout<<" kasdkas"<<endl;
  59. head=head->ll;
  60. }
  61. else
  62. {
  63. // cout<<" creating "<<endl;
  64. head->ll= new node();
  65. head=head->ll;
  66. }
  67. if(var->rr!=NULL)
  68. {
  69. var=var->rr;
  70. ans+=val[i];
  71. }
  72. else
  73. {
  74. var=var->ll;
  75. }
  76. }
  77. }
  78. return ans;
  79. }
  80.  
  81. int main()
  82. {
  83. int n;
  84. cin>>n;
  85. int arr[n+10];
  86. int val[100];
  87. calc(val);
  88. int right[n+10000];
  89. int left[n+1000];
  90. int till_now=0;
  91. for(int i=0;i<n;i++)
  92. {
  93. scanf("%d",&arr[i]);
  94. }
  95. node *head1=new node(),*head2=new node();
  96. till_now=0;
  97. join(head1,val,0);
  98. //cout<<" o inserted "<<endl;
  99. right[0]=arr[0];
  100. for(int i=0;i<n;i++)
  101. {
  102. till_now =till_now ^ arr[i];
  103. int ans=join(head1,val,till_now);
  104. if(i>0)
  105. right[i]=max(right[i-1],ans);
  106. //cout<<" f "<<ans<<endl;
  107. }
  108. // cout<<" fw done "<<endl;
  109. join(head2,val,0);
  110. left[n-1]=arr[n-1];
  111. till_now=0;
  112. for(int i=n-1;i>=0;i--)
  113. {
  114. till_now =till_now ^ arr[i];
  115. int ans=join(head2,val,till_now);
  116. if(i<n-1)
  117. left[i]=max(left[i+1],ans);
  118. // cout<<" b "<<ans<<endl;
  119. }
  120. //cout<<" bw done "<<endl;
  121. int ans=0;
  122. for(int i=0;i<n-1;i++)
  123. {
  124. ans=max(ans,right[i]+left[i+1]);
  125. }
  126. printf("%d\n",ans);
  127. return 0;
  128. }


O(NlogAmax)
--------------------
---------