Lexicographically minimal string rotation - c++

Hi so I'm basically trying to understand this piece of code in regards to determining the lexicographically minimal string rotation but I just can't seem to understand why it works. I understand what the first two ifs do but the third one, when there is a new minimum, it takes the maximum between p and m+l+1. Does anyone have an explanation?
int p = 0, l = 0, m = 0, n = 0;
string inp;
cin >> inp;
n = inp.size();
p = l = 1;
while (p < n && m + l + 1 < n) {
if (inp[m + l] == inp[(p + l) % n])
++l;
if (inp[m + l] < inp[(p + l) % n])
p += l + 1, l = 0;
if (inp[m + l] > inp[(p + l) % n]) {
if (m + l + 1 < p) m = p;
else m = m + l + 1;
p = m + 1;
l = 0;
}
}
cout << m;

Related

XOR of pairwise sum of every unordered pairs in an array

Question Description : Given an array arr[] of length N, the task is to find the XOR of pairwise sum of every possible unordered pairs of the array.
I solved this question using the method described in this post.
My Code :
int xorAllSum(int a[], int n)
{
int curr, prev = 0;
int ans = 0;
for (int k = 0; k < 32; k++) {
int o = 0, z = 0;
for (int i = 0; i < n; i++) {
if (a[i] & (1 << k)) {
o++;
}
else {
z++;
}
}
curr = o * z + prev;
if (curr & 1) {
ans = ans | (1 << k);
}
prev = o * (o - 1) / 2;
}
return ans;
}
Code Descrption : I am finding out at each bit, whether our answer will have that bit set ort not. So to do this for each bit-position, I find the count of all the numbers which have a set bit at the position(represeneted by 'o' in the code) and the count of numbers having un-set bit at that position(represented by 'z').
Now if we pair up these numbers(the numbers having set bit and unset bit together, then we will get a set bit in their sum(Because we need to get XOR of all pair sums).
The factor of 'prev' is included to account for the carry over bits. Now we know that the answer will have a set bit at current position only if the number of set bits are 'odd' as we are doing an XOR operation.
But I am not getting correct output. Can anyone please help me
Test Cases :
n = 3, a[] = {1, 2, 3} => (1 + 2) ^ (1 + 3) ^ (2 + 3)
=> 3 ^ 4 ^ 5 = 2
=> Output : 2
n = 6
a[] = {1 2 10 11 18 20}
Output : 50
n = 8
a[] = {10 26 38 44 51 70 59 20}
Output : 182
Constraints : 2 <= n <= 10^8
Also, here we need to consider UNORDERED PAIRS and not Ordered Pairs for the answer
PS : I know that the same question has been asked before but I couldn't explain my problem with this much detail in the comments so I created a new post. I am new here, so please pardon me and give me your feedback :)
I suspect that the idea in the post you referred to is missing important details, if it could work at all with the stated complexity. (I would be happy to better understand and be corrected should that author wish to clarify their method further.)
Here's my understanding of at least one author's intention for an O(n * log n * w) solution, where w is the number of bits in the largest sum, as well as JavaScript code with a random comparison to brute force to show that it works (easily translatable to C or Python).
The idea is to examine the contribution of each bit one a time. Since in any one iteration, we are only interested in whether the kth bit in the sums is set, we can remove all parts of the numbers that include higher bits, taking them each modulo 2^(k + 1).
Now the sums that would necessarily have the kth bit set are in the intervals, [2^k, 2^(k + 1)) (that's when the kth bit is the highest) and [2^(k+1) + 2^k, 2^(k+2) − 2] (when we have both the kth and (k+1)th bits set). So in the iteration for each bit, we sort the input list (modulo 2^(k + 1)), and for each left summand, we decrement a pointer to the end of each of the two intervals, and binary search the relevant start index.
// https://stackoverflow.com/q/64082509
// Returns the lowest index of a value
// greater than or equal to the target
function lowerIdx(a, val, left, right){
if (left >= right)
return left;
mid = left + ((right - left) >> 1);
if (a[mid] < val)
return lowerIdx(a, val, mid+1, right);
else
return lowerIdx(a, val, left, mid);
}
function bruteForce(A){
let answer = 0;
for (let i=1; i<A.length; i++)
for (let j=0; j<i; j++)
answer ^= A[i] + A[j];
return answer;
}
function f(A, W){
const n = A.length;
const _A = new Array(n);
let result = 0;
for (let k=0; k<W; k++){
for (let i=0; i<n; i++)
_A[i] = A[i] % (1 << (k + 1));
_A.sort((a, b) => a - b);
let pairs_with_kth_bit = 0;
let l1 = 1 << k;
let r1 = 1 << (k + 1);
let l2 = (1 << (k + 1)) + (1 << k);
let r2 = (1 << (k + 2)) - 2;
let ptr1 = n - 1;
let ptr2 = n - 1;
for (let i=0; i<n-1; i++){
// Interval [2^k, 2^(k+1))
while (ptr1 > i+1 && _A[i] + _A[ptr1] >= r1)
ptr1 -= 1;
const idx1 = lowerIdx(_A, l1-_A[i], i+1, ptr1);
let sum = _A[i] + _A[idx1];
if (sum >= l1 && sum < r1)
pairs_with_kth_bit += ptr1 - idx1 + 1;
// Interval [2^(k+1)+2^k, 2^(k+2)−2]
while (ptr2 > i+1 && _A[i] + _A[ptr2] > r2)
ptr2 -= 1;
const idx2 = lowerIdx(_A, l2-_A[i], i+1, ptr2);
sum = _A[i] + _A[idx2]
if (sum >= l2 && sum <= r2)
pairs_with_kth_bit += ptr2 - idx2 + 1;
}
if (pairs_with_kth_bit & 1)
result |= 1 << k;
}
return result;
}
var As = [
[1, 2, 3], // 2
[1, 2, 10, 11, 18, 20], // 50
[10, 26, 38, 44, 51, 70, 59, 20] // 182
];
for (let A of As){
console.log(JSON.stringify(A));
console.log(`DP, brute force: ${ f(A, 10) }, ${ bruteForce(A) }`);
console.log('');
}
var numTests = 500;
for (let i=0; i<numTests; i++){
const W = 8;
const A = [];
const n = 12;
for (let j=0; j<n; j++){
const num = Math.floor(Math.random() * (1 << (W - 1)));
A.push(num);
}
const fA = f(A, W);
const brute = bruteForce(A);
if (fA != brute){
console.log('Mismatch:');
console.log(A);
console.log(fA, brute);
console.log('');
}
}
console.log("Done testing.");

I'm not sure how to refer to the weights in this Neural Network Train method

I'm writing my own implementation of a Neural Network class in C++. I'm not sure how to refer to the weights this statement:
in = in + (inputs [l] * calcWeights [l]) ;
The reason is because there could be more weights than inputs. Here is my code:
void Train (int numInputs, int numOutputs, double inputs [], double outputs []) {
// Set the Random Seed:
srand (time (0)) ;
// Weights (n input(s) * n output(s) = n weight branch(es)):
double calcWeights [numInputs * numOutputs] ;
// Errors (n input(s) * n output(s) = n error branch(es)):
double errors [numInputs * numOutputs] ;
// Set the Weights to random:
for (int j = 0 ; j < numInputs ; j = j + 1) {
calcWeights [j] = ((-1 * numInputs) + (((double) rand ()) % (1 * numInputs))) ;
}
// Train:
int i = 0 ;
double in = 0 ;
double out [numOutputs] ;
while (i < 14999) {
// Get the estimated output:
for (int k = 0 ; k < numOutputs ; k = k + 1) {
for (int l = 0 ; l < numInputs ; l = l + 1) {
in = in + (inputs [l] * calcWeights [l]) ;
}
out [k] = in + GetBias () ;
}
for (int m = 0 ; m < numOutputs ; m = m + 1) {
error [m] = outputs [m] - out [m]
}
// Increment the iterator:
i = i + 1 ;
}
}
From your clarification in comments, I believe modifying your loop a bit will give you what you want.
for (int k = 0 ; k < numOutputs ; k = k + 1) {
in = 0; //Reset in to 0 at the beginning of each output loop
for (int l = 0 ; l < numInputs ; l = l + 1) {
in = in + (inputs [l] * calcWeights [l + k*numInputs]) ;
}
out [k] = in + GetBias () ;
}
You should also make sure you initialize all the weights above.
for (int j = 0 ; j < (numInputs * numOutputs) ; j = j + 1) {
calcWeights [j] = ((-1 * numInputs) + (((double) rand ()) % (1 * numInputs))) ;
}
For a couple of style choices I just want to point out that you can replace k = k + 1 with simply ++k. Likewise you can replace in = in + ...; with in += ...;

"Maximum Sum mod M" ranges in an array: sum and count

Problem
Given an array A = a0,a1,...an, with size up to N ≤ 10^5, and 0 ≤ ai ≤ 10^9.
And a number 0 < M ≤ 10^9.
The task is to find the maximum ∑(k=i, j) ak % M = (ai + ai+1 + a(i+2) + ⋯ + a(j−1) + a(j)) % M, and how many different range(i,j) get that sum.
The complexity has to be less than O(N^2), the latter is too slow.
Example
N = 3, M = 5
A = {2, 4, 3}
The Maximum Sum mod M is 4 and there are 2 ranges, which are a0 to a2 and a1
My attempt
Let's define s[j] = (a0 + a1 + ... + aj) % M so if you want the best sum that ends in j you have to choose an s[i] i < j that s[i] is the smallest sum higher than you.
Because if s[i] > s[j]; s[i] = M - K; K < M - s[j] then the result sum range will be (s[j]-s[i]+M) % M = (s[j] + K) % M and because K < M - s[j] it will increase the result mod M, and as s[j] gets closer to s[j] it will increase the result mod M.
The idea is my attemp, first you have to have to calculate all the sums that starts from 0 and end in a index i, then you can search the smaller value grater than you fast by searching the value with a binary search that the map already have (lower_bound), and count how many time you could do sum with the value that you found. You have to keep the sum somewhere to count how many time you could do it.
#include <iostream>
#include <map>
#define optimizar_io ios_base::sync_with_stdio(false);cin.tie(NULL);
using namespace std;
const int LN = 1e5;
long long N, M, num[LN];
map < long long, int > sum;
int main() {
optimizar_io
cin >> N >> M;
sum[0]++;
long long cont = 0, tmax = 0, res = 1, val;
map < long long, int > :: iterator best;
for (int i = 0; i < N; i++)
{
cin >> num[i];
cont = (cont + num[i]) % M;
if (tmax == cont)
res += sum[0];
if (tmax < cont)
tmax = cont, res = sum[0];
best = sum.lower_bound(cont + 1);
if (best != sum.end())
{
val = cont - (*best).first + M;
if (tmax == val)
res += (*best).second;
if (tmax < val)
tmax = val, res = (*best).second;
}
sum[cont]++;
}
cout << tmax << " " << res;
return 0;
}

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.

Crossword game: read 2d given array and search diagonally c++

This is a crossword game. I wanna read an array diagonally.
I should find some word in all over the 2d given array
this array read from a given file
and it is n*m size; m not always = n
How can I read 2d given diagonally like this:
Example:
m = 4
n = 4
b o o k
z a k o
s l l e
x y z l
ball: found
[b] o o k
z [a] k o
s l [l] e
x y z [l]
foo: not found
Here is the code:
char ReadArray(char* array, int r, int c, int n, int m)
{
return (r > 0 && r <= n && c > 0 && c <= m) ?
array[n * (r - 1) + (c - 1)] : '\0';
}
char readrc(char* array, int r, int c, int n, int m)
{
return (r > 0 && r <= n && c > 0 && c <= m) ?
array[n * (r - 1) + (c - 1)] : '\0';
}
void read_down_right(char* array, int n, int m, vector<string>& list)
{
for (int sc = 2 - n; sc <= m - 1; sc++)
{
string str = "";
for (int r = 1, c = sc; r <= n; r++, c++)
{
char chr = readrc(array, r, c, n, m);
if (chr != '\0')
str += chr;
}
list.push_back(str);
}
}
void read_down_left(char* array, int n, int m, vector<string>& list)
{
for (int sc = 2; sc <= m + n - 2; sc--)
{
string str = "";
for (int r = 1, c = sc; r <= n; r++, c--)
{
char chr = readrc(array, r, c, n, m);
if (chr != '\0')
str += chr;
}
list.push_back(str);
}
}
pass a reference to a blank list each time. list contains all possible strings afterwards, do a linear search.