I want to find the number of even parity numbers between two integers. Here is what I've written so far:
#include <bits/stdc++.h>
using namespace std;
#define fastio \
ios_base::sync_with_stdio(false); \
cin.tie(NULL)
#define ll long long int
bool findParity(ll x)
{
ll y = x ^ (x >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
y = y ^ (y >> 8);
y = y ^ (y >> 16);
if (y & 1)
return 1;
return 0;
}
void solve()
{
ll a,b; cin >> a >> b;
ll evenparity = 0;
for(ll i = a; i <= b; ++i){
if(findParity(i)==0) evenparity++;
}
cout << evenparity;
}
signed main()
{
fastio;
solve();
return 0;
}
This works fine. However, the difference between the two integers a and b can be as high as 10^11, which means that an O(n) solution like this would not work. Is there a more efficient i.e O(1) solution to this problem?
All you need is a function which calculates the even parity numbers from [0-x] interval, let's call it sumParity, then simply return sumParity(b)-sumParity(a-1). (If I understood properly you are looking for the [a,b] closed interval.)
If start counting the parity from zero, and pair the numbers, (0-1), (2,3), (4,5) then each of these pairs has exactly 1 even and 1 odd parity. (These pairs only differ in the lowest bit).
So, if x is odd, then sumParity(x) = (x+1)/2, otherwise x/2 + parity(x).
(You already has the parity(x) function)
f(a,b) = sumParity(b)-sumParity(a-1)
It works only for positive integers, but you can easily extends the logic to negative numbers too.
Every even/odd pair of integers contains exactly one even parity number.
So it suffices to check if a and b are even parity numbers and see if they contribute to their own even/odd pair, and count the intermediate pairs. This is O(1).
Related
Let n an integer and 0<=b<=63, b natural number. Find the b-th bit for the number n on it's 64 bit representation with sign.
and T be the number of test cases.
This is my attempt:
#include <iostream>
#define f cin
#define g cout
using namespace std;
int T;
long long n;
int b;
int main()
{
f >> T;
for(int i = 1; i <= T; ++i)
{
f >> n >> b;
int ans = 0;
bool ok = true;
while(n)
{
if(b == ans)
{
g << n % 2;
ok = false;
break;
}
n /= 2;
++ans;
}
if(ok) g << 0;
}
return 0;
}
but it does not work on all test cases... also is there another way to do this? or is there another way to store the bits? is there some special libraries? can you do this more efficiently with other tools? can you give me some information to read about bitmasks? and where and when you should use them and how are they usefull?
Computers already store the integers in its bitwise representation. All you need are bitwise operators to know a particular bit.
int bthbit(long long n, int b) {
if (n & (1ULL << b)) return 1;
return 0;
}
The solution uses bitwise & operator after left-shifting 1 by b bits. You may want to read about bitwise operators and bitmasks .
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
I now know how it's done in one line, altough I fail to realise why my first draft doesn't work aswell. What I'm trying to do is saving the lower part into a different variable, shifting the higher byte to the right and adding the two numbers via OR. However, it just cuts the lower half of the hexadecimal and returns the rest.
short int method(short int number) {
short int a = 0;
for (int x = 8; x < 16; x++){
if ((number & (1 << x)) == 1){
a = a | (1<<x);
}
}
number = number >> 8;
short int solution = number | a;
return solution;
You are doing it one bit at a time; a better approach would do it with a single operation:
uint16_t method(uint16_t number) {
return (number << 8) | (number >> 8);
}
The code above specifies 16-bit unsigned type explicitly, thus avoiding issues related to sign extension. You need to include <stdint.h> (or <cstdint> in C++) in order for this to compile.
if ((number & (1 << x)) == 1)
This is only going to return true if x is 0. Since 1 in binary is 00000000 00000001, and 1 << x is going to set all but the x'th bit to 0.
You don't care if it's 1 or not, you just care if it's non-zero. Use
if (number & (1 << x))
how can I turn off leftmost non-zero bit of a number in O(1)?
for example
n = 366 (base 10) = 101101110 (in base 2)
then after turning the leftmost non-zero bit off ,number looks like = 001101110
n will always be >0
Well, if you insist on O(1) under any circumstances, the Intel Intrinsics function _bit_scan_reverse() defined in immintrin.h does a hardware find for the most-significant non-zero bit in a int number.
Though the operation does use a loop (functional equivalent), I believe its constant time given its latency at fixed 3 (as per Intel Intrinsics Guide).
The function will return the index to the most-significant non-zero bit thus doing a simple:
n = n & ~(1 << _bit_scan_reverse(n));
should do.
This intrinsic is undefined for n == 0. So you gotta watch out there. I'm following the assumption of your original post where n > 0.
n = 2^x + y.
x = log(n) base 2
Your highest set bit is x.
So in order to reset that bit,
number &= ~(1 << x);
Another approach:
int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >> 1);
}
int main() {
int n = 32767;
int z = highestOneBit(n); // returns the highest set bit number i.e 2^x.
cout<< (n&(~z)); // Resets the highest set bit.
return 0;
}
Check out this question, for a possibly faster solution, using a processor instruction.
However, an O(lgN) solution is:
int cmsb(int x)
{
unsigned int count = 0;
while (x >>= 1) {
++count;
}
return x & ~(1 << count);
}
If ANDN is not supported and LZCNT is supported, the fastest O(1) way to do it is not something along the lines of n = n & ~(1 << _bit_scan_reverse(n)); but rather...
int reset_highest_set_bit(int x)
{
const int mask = 0x7FFFFFFF; // 011111111[...]
return x & (mask >> __builtin_clz(x));
}
Can you explain to me why this doesn't work:
#include <iostream>
using namespace std;
double data_convert(int n);
int main(void) {
cout << data_convert(sizeof(int));
}
double data_convert(int n) {
int i;
double x;
x = 8 * n;
for(i = 0; i < 32; i++)
x = x * 32;
return x;
}
I tried using pow from cmath, but I got the same results. Apparently, this outputs "4.67681e+049". Where as it should output (using Windows Calculator) "4294967296".
The for loop is my own hardcoded pow() function for this specific task. All I wanna do is make a program that can show how big a data type is, along with it's range (bit range or something, yeah?)
If you want 2^32, you should be multiplying by 2 each time. Your code multiplies by 32 each time, so you'll end up with a much larger value.
Also, your x value should start from 1. 8 * n is actually the number of bits in the integer, so that should be your upper limit for the loop:
x = 1;
for (i = 0; i < 8 * n; i++)
x = x * 2;
return x;
A simpler method would be to bitwise negate 0, which will give you the largest possible integer:
return ~0;
will give you 2^32 - 1 = 4294967295 (on a 32-bit machine).
Basically you are multiplying the input by 8 and are then multiplying that by 32, 32 times.
I don't understand what that is suppose to get you to.
If you want the range of an unsigned integer for x amount of bytes you should use this calculation:
max number = 2^(bytes*8) - 1
So in the loop it should multiply 2 until i goes from 0 to bytes*8 and stop there (So it ends before it gets to bytes*8)
I'm not sure what you're doing, but don't you meanx = x*2?