using putchar_unlocked for fast output - c++

I wish to use fast input and output in my code. I understood the use of getchar_unlocked for fast input using the below function.
inline int next_int() {
int n = 0;
char c = getchar_unlocked();
while (!('0' <= c && c <= '9')) {
c = getchar_unlocked();
}
while ('0' <= c && c <= '9') {
n = n * 10 + c - '0';
c = getchar_unlocked();
}
return n;
}
can someone please explain me how to use fast output using putchar_unlocked() function?
I was going through this question and there someone said putchar_unlocked() could be used for fast output.

Well the following code works well for fast output using putchar_unlocked().
#define pc(x) putchar_unlocked(x);
inline void writeInt (int n)
{
int N = n, rev, count = 0;
rev = N;
if (N == 0) { pc('0'); pc('\n'); return ;}
while ((rev % 10) == 0) { count++; rev /= 10;} //obtain the count of the number of 0s
rev = 0;
while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;} //store reverse of N in rev
while (rev != 0) { pc(rev % 10 + '0'); rev /= 10;}
while (count--) pc('0');
}
Normally Printf is quite fast for outputs,however for writing Integer or Long Outputs,the below function is a tad bit faster. Here we use the putchar_unlocked() method for outputting a character which is similar thread-unsafe version of putchar() and is faster.
See Link.

Related

Want to minimize my code so it consumes time less than 1 sec. It uses concept of modular exponentiation .Correct output but exceeding time limit

The below code is to calculate 2^n where n is equal to 1 <= n <= 10^5. So to calculate such large numbers I have used concept of modular exponentian. The code is giving correct output but due to large number of test cases it is exceeding the time limit. I am not getting a way to minimize the solution so it consumes less time. As the "algo" function is called as many times as the number of test cases. So I want to put the logic used in "algo" function in the main() function so it consumes time less than 1 sec and also gives the correct output. Here "t" represents number of test cases and it's value is 1 <= t <= 10^5.
Any suggestions from your side would be of great help!!
#include<iostream>
#include<math.h>
using namespace std;
int algo(int x, int y){
long m = 1000000007;
if(y == 0){
return 1;
}
int k = algo(x,y/2);
if (y % 2 == 1){
return ((((1ll * k * k) % m) * x) % m);
} else if (y % 2 == 0){
return ((1ll * k * k) % m);
}
}
int main(void)
{
int n, t, k;
cin>>t; //t = number of test cases
for ( k = 0; k < t; k++)
{
cin >> n; //power of 2
cout<<"the value after algo is: "<<algo(2,n)<<endl;
}
return 0;
}
You can make use of binary shifts to find powers of two
#include <iostream>
using namespace std;
int main()
{
unsigned long long u = 1, w = 2, n = 10, p = 1000000007, r;
//n -> power of two
while (n != 0)
{
if ((n & 0x1) != 0)
u = (u * w) % p;
if ((n >>= 1) != 0)
w = (w * w) % p;
}
r = (unsigned long)u;
cout << r;
return 0;
}
This is the function that I often use to calculate
Any integer X raised to power Y modulo M
C++ Function to calculate (X^Y) mod M
int power(int x, int y, const int mod = 1e9+7)
{
int result = 1;
x = x % mod;
if (x == 0)
return 0;
while (y > 0)
{
if (y & 1)
result = ( (result % mod) * (x % mod) ) % mod;
y = y >> 1; // y = y / 2
x = ( (x % mod) * (x % mod) ) % mod;
}
return result;
}
Remove the Mod if you don't want.
Time Complexity of this Function is O(log2(Y))
There can be a case of over flow so use int , long , long long etc as per your need.
Well your variables won't sustain the boundary test cases, introducing 2^10000, 1 <= n <= 10^5. RIP algorithms
19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709376
Fear not my friend, someone did tried to solve the problem https://www.quora.com/What-is-2-raised-to-the-power-of-50-000, you are looking for Piyush Michael's answer , here is his sample code
#include <stdio.h>
int main()
{
int ul=16,000;
int rs=50,000;
int s=0,carry[ul],i,j,k,ar[ul];
ar[0]=2;
for(i=1;i<ul;i++)ar[i]=0;
for(j=1;j<rs;j++)
{for(k=0;k<ul;k++)carry[k]=0;
for(i=0;i<ul;i++)
{ar[i]=ar[i]*2+carry[i];
if(ar[i]>9)
{carry[i+1]=ar[i]/10;
ar[i]=ar[i]%10;
}
}
}
for(j=ul-1;j>=0;j--)printf("%d",ar[j]);
for(i=0;i<ul-1;i++)s+=ar[i];
printf("\n\n%d",s);
}

Big primes loop with GMP library C++

It's the first time that I use the gmp library, so I'm really lost, I've found a code implementing the "miller rabin primality test" in c++ but I wanted to be able to apply it to integers with arbitrary precision so I installed the GMP library.
The problem is, I've got no idea of how GMP library actually works (I've read trough a few pages of the manual but I understand very little about it also since I haven't even studied object oriented programming), I want to adapt the primality test to be able to input integers 'num' of about 1000-2000 digits, here's the code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <gmpxx.h>
#include <gmp.h>
#define ll long long
using namespace std;
/*
* calculates (a * b) % c taking into account that a * b might overflow
*/
ll mulmod(ll a, ll b, ll mod)
{
ll x = 0,y = a % mod;
while (b > 0)
{
if (b % 2 == 1)
{
x = (x + y) % mod;
}
y = (y * 2) % mod;
b /= 2;
}
return x % mod;
}
/*
* modular exponentiation
*/
ll modulo(ll base, ll exponent, ll mod)
{
ll x = 1;
ll y = base;
while (exponent > 0)
{
if (exponent % 2 == 1)
x = (x * y) % mod;
y = (y * y) % mod;
exponent = exponent / 2;
}
return x % mod;
}
/*
* Miller-Rabin primality test, iteration signifies the accuracy
*/
bool Miller(ll p,int iteration)
{
if (p < 2)
{
return false;
}
if (p != 2 && p % 2==0)
{
return false;
}
ll s = p - 1;
while (s % 2 == 0)
{
s /= 2;
}
for (int i = 0; i < iteration; i++)
{
ll a = rand() % (p - 1) + 1, temp = s;
ll mod = modulo(a, temp, p);
while (temp != p - 1 && mod != 1 && mod != p - 1)
{
mod = mulmod(mod, mod, p);
temp *= 2;
}
if (mod != p - 1 && temp % 2 == 0)
{
return false;
}
}
return true;
}
//Main
int main()
{
int w=0;
int iteration = 5;
mpz_t num;
cout<<"Enter integer to loop: ";
cin>>num;
if (num % 2 == 0)
num=num+1;
while (w==0) {
if (Miller(num, iteration)) {
cout<<num<<" is prime"<<endl;
w=1;
}
else
num=num+2;
}
system ("PAUSE");
return 0;
}
(If I define num to be 'long long' the program works just fine, but I have no idea how I should adapt the whole thing to "match" num being defined as 'mpz_t' instead, also I didn't mention it but the program basically takes an initial integer value and loops it by adding 2 if the integer is composite until it becomes a prime number)

Recursions and functions c++

I have made a function and I am trying to make it recursive. Does anyone have any tips on how I can make this function recursive? I know recursive means to use the function in the function itself.
int countEven(int n){
int evens = 0;
if(n <= 0) return 0; //base case
while(n > 0){
int digit = n%10; //get the last digit
if(digit%2 == 0){
evens = evens + 1;
}
n = n/10;
}
cout << evens;
}
int rec(int n)
{
int sum = 0;
if(n<=0)
return 0;
else if ((n%10)%2==0)
sum = rec(n/10)+1;
else
sum = rec(n/10);
return sum;
}
Maybe something like this :)
For counting the even digits of an integer base 10 you can simplify the function to the following
int countEven(int n)
{
if (n != 0) return !(n % 2) + countEven(n/10);
else return 0;
}
This expands as follows. Assume n = 258:
countEven(258) =
1 + countEven(25) =
1 + 0 + countEven(2) =
1 + 0 + 1 + countEven(0) = 2
Note that the statement !(n % 2) returns 1 if n is even and 0 if it's odd.
For shorter you can do the following:
int ce(int n) { return n ? !(n&1) + ce(n/10) : 0; }
using the ternary operator.
seems like you're trying to count the even digits in a number
int countEven(int n){
if(n == 0)
return 0; //base case
if (n<10)
return !(n%2);
return !(n%2)+countEven(n/10);
}
looks like a similar question i received from QC.
to make it recursive, you must have the function calling onto itself. Ask how you can make the the input simpler and have some sort of base so that the function doesn't break.
int countEven(int number) {
if (x <= 0) return 0;
if (x % 2 == 0) {
return countEven(number / 10) + 1;
}
return countEven(number / 10)
}

Modulo of difference of terms

As an answer to a particular problem, I have to print n*k^n - (n-1)*k.
for(i=0;i<n;i++){
c=(c%p*k%p)%p;
c=(c%p*n%p)%p;
d=((n-1)%p*k%p)%p;
s=(c%p-d%p)%p;
cout<<s<<endl;
}
Initially c=1, p=1000000007 and s is my final answer.
I have to take the modulo of s with respect to p.
For large values of n, s becomes negative. This happens because the modulo value changes. So even if c>d, it is possible that c%p<d%p. For n=1000000000 and k=25, s=-727999801. I am not being able to think of a suitable workaround.
-2 % 7 = 5, because -2 = 7 * (-1) + 5, while c++ modulo operation would return -2, so to get positive number you just need to add p.
if (s < 0) s += p;
I advise you to rewrite your code in the following way:
for (int i = 0; i < n; i++) {
c = (c * (k % p)) % p;
}
c = (c * (n % p)) % p;
int d = ((n - 1) % p * (k % p)) % p;
int s = (c - d) % p;
if (s < 0) s += p;
cout << s << endl;
To check with some small inputs you can use the following line:
cout << (n * (int)pow(k, n) - (n-1)*k) % p << endl;
Try to run with this input:
const int n = 5;
const int p = 7;
const int k = 10;
int c = 1;
You will see that without if (s < 0) s += p; it is -1. This line fixes it to 6 - the right answer.

c++ Decimal to binary, then use operation, then back to decimal

I have an array with x numbers: sets[ ](long numbers) and a char array operations[ ] with x-1 numbers. For each number from sets[ ], its binary form(in 64bits) would be the same as a set of numbers( these numbers being from 0 to 63 ), 1's and 0's representing whether it is inside a subset or not ( 1 2 4 would be 1 1 0 1, since 3 is missing)
ex: decimal 5 --->000...00101 , meaning that this subset will only have those 2 last numbers inside it(#63 and #61)
now,using the chars i get in operations[], i should work with them and the binaries of these numbers as if they were operations on subsets(i hope subset is the right word), these operations being :
U = reunion ---> 101 U 010 = 111
A = intersection ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> like the previous one
so basically I'd have to read numbers, make them binary, use them as if they were sets and use operations accordingly, then return the result of all these operations on them.
my code :
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
So everything seems fine, except when im trying this :
sets = {5, 2, 1}
operations = {'U' , '\'}
5 U 2 is 7(111), and 7 \ 1 is 6 (111 - 001 = 110 --> 6)
the result should be 6, however when i Input them like that the result is 4 (??)
however, if i simply input {7,1} and { \ } the result is 6,as it should be. but if i input them like i first mentioned {5,2,1} and {U,} then its gonna output 4.
I can't seem to understand or see what im doing wrong...
You don't have to "convert to binary numbers".
There's no such thing as 'binary numbers'. You can just perform the operations on the variables.
For the reunion, you can use the bitwise OR operator '|', and for the intersection, you can use the bitwise AND operator '&'.
Something like this:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\\')
result = a - b;
else if (op == '/')
result = b - a;
Use bitwise operators on integers as shown in #Hugal31's answer.
Note that integer size is usually 32bit, not 64bit. On a 64bit system you need long long for 64bit integer. Use sizeof operator to check. int is 4 bytes (32bit) and long long is 8 bytes (64bit).
For the purpose of homework etc., your conversion to vector cannot be right. You should test it to see if it outputs the correct result. Otherwise use this:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
Note the use of shift operators. To AND the numbers you can do something like the following:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
This is of course pointless because you can just say int result = X & Y;