Given N integers, remove 1 of them so that their XOR is as large as possible - c++

You are given N 64-bit integers (or long longs). You need to remove one of then so that the XOR of those N-1 (all of them without the one that has been removed) integers, is as large as possible. Print out the XOR in the console. The number of integers will not exceed 1e6.
By XOR of all the integers I mean something like this:
long long myXor=0;
for(int i = 0;i<arr.size();i++){
myXor=xor(myXor,arr[i]);
}
Also, this is not my homework. I know posting homework here is frowned upon. I've been trying to solve this my self, but I've only come up with solutions that work in O(n^2).

(Intelligent) brute-forcing might actually be the best thing.
And you won't even need O(n²) for that.
Since xor is reversible you can calculate the xor of all numbers first and xor again with one number to get the xor of all except that number.
Using this it is quite easy to reduce the brute-force solution to O(n):
long long xorAll = 0;
for(int i = 0;i<arr.size();i++){
xorAll = myXor^arr[i];
}
long long max = LONG_LONG_MIN; // Store the maximum number.
for(int i = 0; i < arr.size(); i++) {
if((xorAll^arr[i]) > max)
max = xorAll^arr[i];
}

#include <iostream>
#include <limits.h>
typedef long long ll;
const int MAX_N = 1000000;
int main() {
// initialize the total xor
ll tot = 0;
// static allocation is faster :)
ll nums[MAX_N];
// read in the number of elements
int n;
std::cin >> n;
for (int i = 0; i < n; i ++) {
std::cin >> nums[i];
// use the built in xor operator (^)
tot ^= nums[i];
}
// initialize the maximum value to the smallest possible long
ll maxVal = LONG_LONG_MIN;
for (int i = 0; i < n; i ++) {
// xor undos itself so this is essentially removing nums[i]
ll val = tot ^ nums[i];
// if it's larger than the max then update the max
if (val > maxVal) {
maxVal = val;
}
}
// output it
std::cout << maxVal << std::endl;
}

There are other answers showing how this can be done in O(n) time quite easily, e.g.
// xor all the numbers
long long myXor = 0;
for(auto n : arr) {
myXor ^= n;
}
// find the max
long long max = std::numeric_limits<long long>::min();
for(auto n : arr) {
max = std::max(max, myXor ^ n);
}
However, you can use the property that the xor operations can be done out of order. This lets you use the reduce function in numeric, like so
// xor all the numbers
auto myXor = std::reduce(arr.cbegin(), arr.cend(), 0ll, std::bit_xor{});
auto choose = [myXor] (auto max, auto n) { return std::max(max, myXor ^ n);};
// find the max
auto max = std::reduce(arr.cbegin(), arr.cend(),
std::numeric_limits<long long>::min(), choose);
Here is a quick and dirty comparison between the 2 solutions, that show a considerable speedup (about 40% for 1e6 numbers).

Related

Hackerrank repeated string, hign value not printing in c++

The below given code is not working for high value (eg: 51574523448, 1000000000000, etc) even after using long long and giving some different different values but is properly working for low values.
Can anyone explain what is the problem and how to solve it. (Sorry for weak english).
int repeatedString(string s, long n) {
long count = 0;
int secondCount = 0;
long num;
int length = s.length();
double remainder;
num = (long) n / (length);
remainder = n % (length);
for(int i=0; i < length; i++) {
if(s[i]=='a') {
count++;
if(i < remainder)
secondCount++;
}
}
count = count*num + secondCount;
return count;
}
Try running this program on your platform:
#include <iostream>
#include <limits>
int main()
{
std::cout << std::numeric_limits<long>::max() << '\n';
}
The number it prints is the maximum value a long can store. I get 2147483647, which is much less than 51574523448. You will likely need to use a larger data type, such as long long.

Overflow on Multiplication in C++

In my code I am trying to multiply two numbers. The algorithm is simple as (k)*(k-1)^n. I stored the product (k-1)^n in variable p1 and then I multiply it with k. For n=10, k=10 (k-1)^n-1 should be 387420489 and I got this in variable p1 but on multiplying it with k, I get a negative number. I used modulus but instead of 3874208490, I get some other large positive number. What is the correct approach?
#include <iostream>
using namespace std;
typedef long long ll;
ll big = 1000000000 + 7;
ll multiply(ll a, ll b)
{
ll ans = 1;
for (int i = 1; i <= b; i++)
ans = ans * a;
return ans % big;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n, k;
cin >> n >> k;
ll p1 = multiply(k - 1, n - 1);
cout << p1 << endl; // this gives correct value
ll p2 = (k % big) * (p1 % big);
cout << ((p2 + big) % big) % big << endl;
}
}
What is ll type? If it is just int (and I pretty sure it is), it gets overflowed, because 32-bit signed type can't store values more than (2^31)-1, which approximately equals to 2 * 10^9. You can use long long int to make it work, then your code will work with the results less than 2^63.
It's not surprising you get an overflow. I plugged your equation into wolfram alpha, fixing n at 10 and iterating over k from 0 to 100.
The curve gets very vertical, very quickly at around k = 80.
10^21 requires 70 binary bits to represent it, and you only have 63 in a long long.
You're going to have to decide what the limits of this algorithm's parameters are and pick data types corresponding. Perhaps a double would be more suitable?
link to plot is here

Using binary search to find k-th largest number in n*m multiplication table

So, I am trying to solve the problem: http://codeforces.com/contest/448/problem/D
Bizon the Champion isn't just charming, he also is very smart.
While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted an n × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?
Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.
Input
The single line contains integers n, m and k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).
Output
Print the k-th largest number in a n × m multiplication table.
What I did was, I applied binary search from 1 to n*m looking for the number which has exactly k elements less than it. For this, I made the following code:
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
ll n,m;
int f (int val);
int min (int a, int b);
int main (void)
{
int k;
cin>>n>>m>>k;
int ind = k;
ll low = 1LL;
ll high = n*m;
int ans;
while (low <= high)
{
ll mid = low + (high-low)/2;
if (f(mid) == k)
ans = mid;
else if (f(mid) < k)
low = mid+1;
else
high = mid-1;
}
cout<<ans<<"\n";
return 0;
}
int f (int val)
{
int ret = 0;
for ( int i = 1; i <= n; i++ )
{
ret = ret + min(val/i,m);
}
return ret;
}
int min (int a, int b)
{
if (a < b)
return a;
else
return b;
}
However, I don't know why but this gives wrong answer on test cases:
input
2 2 2
output
2
My output comes out to be 0
I am learning binary search but I don't know where am I going wrong with this implementation. Any help will be appreciated.
Ignoring the fact that your binary search is not the fastest method, you still want to know why it is incorrect.
First be very clear about what you want and what your f is returning:
looking for the number which has exactly k elements less than it.
No! You are looking for the smallest number that has k elements less than or equal to it. And your function f(X) returns the count of elements less than or equal to X.
So when f(X) returns a value too small, you know X must be larger by at least 1, so low=mid+1 is correct. But when f(X) returns a value too large, X might be perfect (might be an element appearing several times in the table). Conversely, when f(X) returns exactly the right number, X might still be too big (X might be a value that appears zero times in the table).
So when f(X) is not too small, the best you can do is high=mid not high=mid-1
while (low < high)
{
ll mid = low + (high-low)/2;
if (f(mid) < k)
low = mid+1;
else
high = mid;
}
Notice low never gets > high, so stop when they are equal, and we don't try to catch the ans along the way. Instead at the end low==high==Answer
The contest says 1 second time limit. On my computer, your code with that correction solves the max size problem in under a second. But I'm not sure the judging computer is that fast.
Edit: int is too small for the max size of the problem, so you can't return int from f:
n, m, and i each fit in 32 bits, but the input and output of f() as well as k, ret, low and high all need to hold integers up to 2.5e11
import java.util.*;
public class op {
static int n,m;
static long k;
public static void main(String args[]){
Scanner s=new Scanner(System.in);
n=s.nextInt();
m=s.nextInt();
k=s.nextLong();
long start=1;
long end=n*m;
long ans=0;
while(end>=start){
long mid=start+end;
mid/=2;
long fmid=f(mid);
long gmid=g(mid);
if(fmid>=k && fmid-gmid<k){
ans=mid;
break;
}
else if(f(mid)>k){
end=mid-1;
}
else{
start=mid+1;
}
}
System.out.println(ans);
}
static long f (long val)
{
long ret = 0;
for ( int i = 1; i <= n; i++ )
{
ret = ret + Math.min(val/i,m);
}
return ret;
}
static long g (long val)
{
long ret = 0;
for ( int i = 1; i <= n; i++ )
{
if(val%i==0 && val/i<=m){
ret++;
}
}
return ret;
}
public static class Pair{
int x,y;
Pair(int a,int b){
x=a;y=b;
}
}
}

Generate all combinations in bit version

I'd like to generate all possible combination (without repetitions) in bit representation. I can't use any library like boost or stl::next_combination - it has to be my own code (computation time is very important).
Here's my code (modified from ones StackOverflow user):
int combination = (1 << k) - 1;
int new_combination = 0;
int change = 0;
while (true)
{
// return next combination
cout << combination << endl;
// find first index to update
int indexToUpdate = k;
while (indexToUpdate > 0 && GetBitPositionByNr(combination, indexToUpdate)>= n - k + indexToUpdate)
indexToUpdate--;
if (indexToUpdate == 1) change = 1; // move all bites to the left by one position
if (indexToUpdate <= 0) break; // done
// update combination indices
new_combination = 0;
for (int combIndex = GetBitPositionByNr(combination, indexToUpdate) - 1; indexToUpdate <= k; indexToUpdate++, combIndex++)
{
if(change)
{
new_combination |= (1 << (combIndex + 1));
}
else
{
combination = combination & (~(1 << combIndex));
combination |= (1 << (combIndex + 1));
}
}
if(change) combination = new_combination;
change = 0;
}
where n - all elements, k - number of elements in combination.
GetBitPositionByNr - return position of k-th bit.
GetBitPositionByNr(13,2) = 3 cause 13 is 1101 and second bit is on third position.
It gives me correct output for n=4, k=2 which is:
0011 (3 - decimal representation - printed value)
0101 (5)
1001 (9)
0110 (6)
1010 (10)
1100 (12)
Also it gives me correct output for k=1 and k=4, but gives me wrong outpu for k=3 which is:
0111 (7)
1011 (11)
1011 (9) - wrong, should be 13
1110 (14)
I guess the problem is in inner while condition (second) but I don't know how to fix this.
Maybe some of you know better (faster) algorithm to do want I want to achieve? It can't use additional memory (arrays).
Here is code to run on ideone: IDEONE
When in doubt, use brute force. Alas, generate all variations with repetition, then filter out the unnecessary patterns:
unsigned bit_count(unsigned n)
{
unsigned i = 0;
while (n) {
i += n & 1;
n >>= 1;
}
return i;
}
int main()
{
std::vector<unsigned> combs;
const unsigned N = 4;
const unsigned K = 3;
for (int i = 0; i < (1 << N); i++) {
if (bit_count(i) == K) {
combs.push_back(i);
}
}
// and print 'combs' here
}
Edit: Someone else already pointed out a solution without filtering and brute force, but I'm still going to give you a few hints about this algorithm:
most compilers offer some sort of intrinsic population count function. I know of GCC and Clang which have __builtin_popcount(). Using this intrinsic function, I was able to double the speed of the code.
Since you seem to be working on GPUs, you can parallelize the code. I have done it using C++11's standard threading facilities, and I've managed to compute all 32-bit repetitions for arbitrarily-chosen popcounts 1, 16 and 19 in 7.1 seconds on my 8-core Intel machine.
Here's the final code I've written:
#include <vector>
#include <cstdio>
#include <thread>
#include <utility>
#include <future>
unsigned popcount_range(unsigned popcount, unsigned long min, unsigned long max)
{
unsigned n = 0;
for (unsigned long i = min; i < max; i++) {
n += __builtin_popcount(i) == popcount;
}
return n;
}
int main()
{
const unsigned N = 32;
const unsigned K = 16;
const unsigned N_cores = 8;
const unsigned long Max = 1ul << N;
const unsigned long N_per_core = Max / N_cores;
std::vector<std::future<unsigned>> v;
for (unsigned core = 0; core < N_cores; core++) {
unsigned long core_min = N_per_core * core;
unsigned long core_max = core_min + N_per_core;
auto fut = std::async(
std::launch::async,
popcount_range,
K,
core_min,
core_max
);
v.push_back(std::move(fut));
}
unsigned final_count = 0;
for (auto &fut : v) {
final_count += fut.get();
}
printf("%u\n", final_count);
return 0;
}

factorial of big numbers with strings in c++

I am doing a factorial program with strings because i need the factorial of Numbers greater than 250
I intent with:
string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;
}
}
But the problem is that atoi not works. How can i convert my string in a integer.
And The most important Do I want to know if the program of this way will work with the factorial of 400 for example?
Not sure why you are trying to use string. Probably to save some space by not using integer vector? This is my solution by using integer vector to store factorial and print.Works well with 400 or any large number for that matter!
//Factorial of a big number
#include<iostream>
#include<vector>
using namespace std;
int main(){
int num;
cout<<"Enter the number :";
cin>>num;
vector<int> res;
res.push_back(1);
int carry=0;
for(int i=2;i<=num;i++){
for(int j=0;j<res.size();j++){
int tmp=res[j]*i;
res[j]=(tmp+carry)%10 ;
carry=(tmp+carry)/10;
}
while(carry!=0){
res.push_back(carry%10);
carry=carry/10;
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
return 0;
}
Enter the number :400
Factorial of 400 :64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
There's a web site that will calculate factorials for you: http://www.nitrxgen.net/factorialcalc.php. It reports:
The resulting factorial of 250! is 493 digits long.
The result also contains 62 trailing zeroes (which constitutes to 12.58% of the whole number)
3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000
Many systems using C++ double only work up to 1E+308 or thereabouts; the value of 250! is too large to store in such numbers.
Consequently, you'll need to use some sort of multi-precision arithmetic library, either of your own devising using C++ string values, or using some other widely-used multi-precision library (GNU GMP for example).
The code below uses unsigned double long to calculate very large digits.
#include<iostream.h>
int main()
{
long k=1;
while(k!=0)
{
cout<<"\nLarge Factorial Calculator\n\n";
cout<<"Enter a number be calculated:";
cin>>k;
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
}
else
{
int numArr[10000];
int total,rem=0,count;
register int i;
//int i;
for(i=0;i<10000;i++)
numArr[i]=0;
numArr[10000]=1;
for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem;
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total;
}
i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is \n\n";
for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}
cout<<"\n\n";
}//while
return 0;
}
Output:
![Large Factorial Calculator
Enter a number be calculated:250
The factorial of 250 is
32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
You can make atoi compile by adding c_str(), but it will be a long way to go till getting factorial. Currently you have no b around. And if you had, you still multiply int by int. So even if you eventually convert that to string before return, your range is still limited. Until you start to actually do multiplication with ASCII or use a bignum library there's no point to have string around.
Your factorial depends on conversion to int, which will overflow pretty fast, so you want be able to compute large factorials that way. To properly implement computation on big numbers you need to implement logic as for computation on paper, rules that you were tought in primary school, but treat long long ints as "atoms", not individual digits. And don't do it on strings, it would be painfully slow and full of nasty conversions
If you are going to solve factorial for numbers larger than around 12, you need a different approach than using atoi, since that just gives you a 32-bit integer, and no matter what you do, you are not going to get more than 2 billion (give or take) out of that. Even if you double the size of the number, you'll only get to about 20 or 21.
It's not that hard (relatively speaking) to write a string multiplication routine that takes a small(ish) number and multiplies each digit and ripples the results through to the the number (start from the back of the number, and fill it up).
Here's my obfuscated code - it is intentionally written such that you can't just take it and hand in as school homework, but it appears to work (matches the number in Jonathan Leffler's answer), and works up to (at least) 20000! [subject to enough memory].
std::string operator*(const std::string &s, int x)
{
int l = (int)s.length();
std::string r;
r.resize(l);
std::fill(r.begin(), r.end(), '0');
int b = 0;
int e = ~b;
const int c = 10;
for(int i = l+e; i != e;)
{
int d = (s[i]-0x30) * x, p = i + b;
while (d && p > e)
{
int t = r[p] - 0x30 + (d % c);
r[p] = (t % c) + 0x30;
d = t / c + d / c;
p--;
}
while (d)
{
r = static_cast<char>((d % c) +0x30)+r;
d /= c;
b++;
}
i--;
}
return r;
}
In C++, the largest integer type is 'long long', and it hold 64 bits of memory, so obviously you can't store 250! in an integer type. It is a clever idea to use strings, but what you are basically doing with your code is (I have never used the atoi() function, so I don't know if it even works with strings larger than 1 character, but it doesn't matter):
covert the string to integer (a string that if this code worked well, in one moment contains the value of 249!)
multiply the value of the string
So, after you are done multiplying, you don't even convert the integer back to string. And even if you did that, at one moment when you convert the string back to an integer, your program will crash, because the integer won't be able to hold the value of the string.
My suggestion is, to use some class for big integers. Unfortunately, there isn't one available in C++, so you'll have to code it by yourself or find one on the internet. But, don't worry, even if you code it by yourself, if you think a little, you'll see it's not that hard. You can even use your idea with the strings, which, even tough is not the best approach, for this problem, will still yield the results in the desired time not using too much memory.
This is a typical high precision problem.
You can use an array of unsigned long long instead of string.
like this:
struct node
{
unsigned long long digit[100000];
}
It should be faster than string.
But You still can use string unless you are urgent.
It may take you a few days to calculate 10000!.
I like use string because it is easy to write.
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
const int MAXN = 90;
int n, m;
int a[MAXN];
string base[MAXN], f[MAXN][MAXN];
string sum, ans;
template <typename _T>
void Swap(_T &a, _T &b)
{
_T temp;
temp = a;
a = b;
b = temp;
}
string operator + (string s1, string s2)
{
string ret;
int digit, up = 0;
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) Swap(s1, s2), Swap(len1, len2);
while(len2 < len1) s2 = '0' + s2, len2++;
for (int i = len1 - 1; i >= 0; i--)
{
digit = s1[i] + s2[i] - '0' - '0' + up; up = 0;
if (digit >= 10) up = digit / 10, digit %= 10;
ret = char(digit + '0') + ret;
}
if (up) ret = char(up + '0') + ret;
return ret;
}
string operator * (string str, int p)
{
string ret = "0", f; int digit, mul;
int len = str.length();
for (int i = len - 1; i >= 0; i--)
{
f = "";
digit = str[i] - '0';
mul = p * digit;
while(mul)
{
digit = mul % 10 , mul /= 10;
f = char(digit + '0') + f;
}
for (int j = 1; j < len - i; j++) f = f + '0';
ret = ret + f;
}
return ret;
}
int main()
{
freopen("factorial.out", "w", stdout);
string ans = "1";
for (int i = 1; i <= 5000; i++)
{
ans = ans * i;
cout << i << "! = " << ans << endl;
}
return 0;
}
Actually, I know where the problem raised At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}
Expexted output for 14! = 87178291200
The logic should be:
unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}
However b may get overflowed. So you may use a bigger integral type.
Or you can use float type which is inaccurate but can hold much bigger numbers.
But it seems none of the built-in types are big enough.