Miscelleneous Problems Lectures added

This commit is contained in:
InstructorAnshul 2019-11-29 15:51:08 +05:30
parent ec8b7eb5ac
commit 6ca41be67e
5 changed files with 2016 additions and 0 deletions

View File

@ -0,0 +1,317 @@
# Miscelleneous Problems 12
## 423 Good Graph
### Problem Statement
Given a directed graph of N nodes where each node is pointing to any one of the N nodes (can possibly point to itself). Ishu, the coder, is bored and he has discovered a problem out of it to keep himself busy. Problem is as follows:
A node is ```'good' ```if it satisfies one of the following:
```
1. It is the special node (marked as node 1)
2. It is pointing to the special node (node 1)
3. It is pointing to a good node.
```
Ishu is going to change pointers of some nodes to make them all 'good'. You have to find the min. number of pointers to change in order to
make all the nodes good (Thus, a Good Graph).
Note: Resultant Graph should hold the property that all nodes are good and each node must point to exactly one node.
**Constraints:**
```
1 <= N <= 100,000
```
**Input:**
```
A vector of N integers containing N numbers
all between 1 to N, where i-th number is
the number of node that i-th node is pointing to.
```
**Output:**
```
An Integer denoting min. number of pointer changes.
```
**Example:**
```C++
input: [1, 2, 1, 2]
output: 1 (Pointer of node 2 is made to point to node 1)
input: [3, 1, 3, 1]
output: 1 (Pointer of node 3 is made to point to node 1)
```
### Wrong Approach
- Initialize count = 0.
- From every point do a BFS/DFS. If you can't reach any special node, increase count by 1.
- This approach will tell us the total number of non-good nodes.
- We can change the pointer in every good node. Thus we can say after count number of pointer changes we will have a good graph.
- This approach is wrong. Because there might a case like following:
```C++
input: [1,2,1,2]
```
- Here if we change the pointer of second element, we do not need to change the pointer of forth element. Thus we can say the minimum pointer change is 1. Here, the count of non-good nodes is two.
- How can we improve this approach?
### Brute Force
- For every node find the top most node that can reached from it.
- Save that node in a set.
- Return set.size()
### Hints
- We can see that if there is path from a node to a good node then it is a good node.
- If we can reach a good node from a given node we can mark it as good node.
- If we can not reach a good node from a given node, we will need at least one pointer change to make it good.
- If there is a chain like $5->4->3->2->4$. Now, if we change pointer of 4 to 1, all the nodes will become good.
- So, we can see again we just one pointer change to make the whole chain good.
- Let's color all the chains one by one.
- Since every node is only connected to at maximum one other node. BFS and DFS are same. It is similar to linked list traversal.
```C++
input: [1,2,2,3,4,5,7,7,8,9]
Linked list representation:
1
2<-2<-3<-4<-5<-6
7<-7<-8<-9<-10
```
### Code
```C++
int Solution::solve(vector<int> &A) {
int n = A.size();
bool good[n];
good[0] = true;
for(int i = 1; i < n; i += 1){
good[i] = false;
}
bool visited[n];
for(int i = 0; i < n; i += 1){
visited[i] = false;
}
int curr, next;
int ans = 0, c = 0;
int color[n];
for(int i = 0; i < n; i += 1) {
if(visited[i] == false){
curr = i;
visited[i] = true;
next = A[curr] - 1;
color[curr] = c;
while(visited[next] == false){
good[curr] = true;
visited[next] = true;
color[next] = c;
curr = next;
next = A[curr] - 1;
}
if(color[next] == c && next != 0 ){
ans += 1;
}
c += 1;
}
}
return ans;
}
```
### Time Complexity
Since every node will be visited at max twice, the time complexity will be $O(n)$.
### Dry Run
|Visited|Color|Good|i|A|count|
|:--|:--|:--|:--|:--|:--|
|[f,f,f,f,f,f]|[]|[t,f,f,f,f,f]|0|[1,2,2,5,6,3]|0|
|[t,f,f,f,f,f]|[0,]|[t,f,f,f,f,f]|1|[1,2,2,5,6,3]|0|
|[t,t,f,f,f,f]|[0,1]|[t,t,f,f,f,f]|2|[1,2,2,5,6,3]|1|
|[t,t,t,f,f,f]|[0,1,2]|[t,t,t,f,f,f]|3|[1,2,2,5,6,3]|1|
|[t,t,t,t,t,t]|[0,1,2,3,3,3]|[t,t,t,t,t,t]|4|[1,2,2,5,6,3]|1|
|All visited||||||
[Good Graph](https://www.interviewbit.com/hire/test/problem/423/)
## 438 King Graph
### Problem
Kingdom JenaRajya is a well planned kingdom. They have N houses numbered [0,1,..,N-1] in the city and some bidirectional roads connecting the houses. King Jena has decided to meet his people and so he will visit one of the house in the kingdom where others can gather and meet him. King Jena is very kind and do not want anyone to travel far to meet him. So, he has come up with the following criteria to decide the house he will be visiting:
Assuming that the people from other houses will take the shortest possible path to reach the house the king is visiting, King Jena wants to minimize the maximum distance one has to travel to meet him. In other words, he will choose the house where the shortest distance to the farthest house is minimum possible.
Output the house number which King Jena will visit.
**Note:**
1. In case there is a tie, he will visit the house with minimum house number.
2. You can assume that the graph is connected and so everyone will be able to visit.
**Constraints:**
1 <= N <= 500
1 <= Length of road <= 1000000
**Input format:**
Adjacency matrix representation of the graph.
A[i][j] = distance between house i and j. (A[i][i] = 0 and A[i][j] = -1, if house i and house j have no road between them)
As the roads are bidirectional, A[i][j] = A[j][i]
**Example:**
```C++
Input:
A = [[0, 6, 8, -1],
[6, 0, 9, -1],
[8, 9, 0, 4],
[-1, -1, 4, 0]]
Output:
2
```
### Brute Force
- We can run Dijkstra from each house to find the distance of every other house to this house.
- We can get a distance matrix for each node.
- Then we can find for every house the distance of the furtherest house from that house.
- Find the house which has minimum such distance.
- Time Complexity $O(V* ElogV)$
### Hint
- $E$ can be as big as $V^2$. The above brute force can take $O(V^3logV)$.
- We can reduce the time complexity by using Floyd Warsal all pair shortest path algorithm.
- Floyd Warsal will take only $O(V^3)$ time. This is not much better. However, the implementation is much simpler.
- Inductive Hypothesis
- Suppose that prior to the kth iteration it holds that for $i, j \in V$, $d_{ij}$ contains the length of the shortest path Q from i to j in G containing only vertices in the set ${1, 2, ..., k 1}$
- We can prove floyd warsal using this hypothesis.
### Code
```C++
#define INF 1000000000
int Solution::solve(vector<vector<int> >& A){
//No. of places
int n = A.size();
//Floyd-Warshall Algorithm implementation to find all pairs shortest paths
vector<vector<int> > d(n,vector<int>(n,INF));
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(A[i][j] != -1) d[i][j] = A[i][j];
}
}
for(int i=0; i<n; i++) d[i][i]=0;
for(int k=0; k<n; k++)
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(d[i][j] > d[i][k]+d[k][j])
d[i][j] = d[i][k]+d[k][j];
//Find the required answer
int maxDist = -1, ans = -1, temp = INF;
for(int i=0; i<n; i++){
maxDist = -1;
for(int j=0; j<n; j++) maxDist = max(d[i][j], maxDist);
if(maxDist < temp){
temp = maxDist; ans = i;
}
}
return ans;
}
```
### Time Complexity
- $O(V^3)$
### Dry Run
- Adjacency Matrix : $\begin{bmatrix}
0&3&6\\
3&0&2\\
6&2&0
\end{bmatrix}$
- Distance Matrix :$\begin{bmatrix}
0&3&5\\
3&0&2\\
5&2&0
\end{bmatrix}$
- We can see that the answer will be node at index 1. As the distances are ${3,0,2}$ for it.
[King Graph](https://www.interviewbit.com/admin/new_problems/438/#/hints)
## 441 Snake And Ladder Game
### Problem Statement
Given a `snake and ladder` board.
You have to find the ```minimum number of dice throws``` required to reach the last cell(Nth cell) from first cell(1st cell).
For example:
![before](https://images8.alphacoders.com/448/448009.jpg)
```
Here N is 30 and you have to reach 30 from 1.
Here minimum number of dice throws are 3
In first dice throw you will get a 2
In second dice throw you will get a 6
And in third dice throw you will get a 2
```
For snake and ladders there are two arrays A and B of same size.
Ladder or a Snake at position A[i] will take you to a position B[i].
[Snake And Ladder](https://www.interviewbit.com/hire/test/problem/441/)
### Easier Problem
- If there were no snakes and ladders, the problem will become simpler. We can visit 6th node after the given node in one roll. So, for n we will need to do ceiling of $n/6$ rolls.
### Hint
- Having snakes and ladders changes the problem. Jumping to the 6th node might not be optimal.
- Here we can replace every node i that has a ladder to j or snake to j with j.
- Now, we can do a bfs to find the shortest path.
### Code
```C++
int solve(int N, vector<int> &A, vector<int> &B)
{
vector<int> moves(N+1, -1);
vector<bool> visited(N+1, false);
for(int i=0;i<A.size();i++){
moves[A[i]] = B[i];
}
queue<pair<int,int> > que;
que.push(make_pair(1,0));
pair<int,int> entryExtracted ;
visited[1]=true;
while(!que.empty())
{
entryExtracted = que.front();
if(entryExtracted.first==N)
break;
que.pop();
for(int i=entryExtracted.first+1;i<=entryExtracted.first+6 && i<=N;i++)
{
pair<int,int> entry;
if(!visited[i])
{
entry.second = entryExtracted.second+1;
visited[i]=true;
if(moves[i]!=-1)
{
entry.first = moves[i];
}else
entry.first =i;
que.push(entry);
}
}
}
return entryExtracted.second;
}
```

View File

@ -0,0 +1,569 @@
# Miscelleneous Problems 13
## Game Of Ways
### Problem Statement
Batman is about to take off from Gothams airport which has m runways(numbered from 1 to m) of length n units.
As always, the Joker has come up with an insane game to have fun with Batman.
The rules of the game are as follows::
- Batmans plane can take off only after running for n-units distance in the runways.
- Batman can start on any runway and end on any runway.
- Batman can switch his plane from runway i to j only if i and j are coprime.
- If the batman fails to switch his plane to a coprime runway, after running for 1 unit distance on a single runway, the Joker will bomb the plane.
The Joker does not want to kill the batman, because what will he do without him. So he asks for your help to find out number of ways in which Batman can take off his plane without getting bombed.
As the answer can be very large, output answer modulo (1000000007)
----------
**Input Format**
```
First argument given is an Integer A, Length of the runway.
Second argument given is an Integer B,
Number of different runways available
```
**Output Format**
```
Return a single integer X, the number of ways Batman can take off his plane without getting bombed.
As X can be very large, return X MOD 10^9+7
```
**Constraints**
```
1 <= A <= 1000000000
0 <= B <= 10
```
**For Example**
```C++
Input 1:
A = 1
B = 3
Output 1:
3
Input 2:
A = 2
B = 3
Output 1:
7
Explanation:
For test 1:
3 Ways Starting at 1, 2, 3
For test 2:
1st way: starting and covering whole distance at runway 1.
i.e 1 -> 1 (1 and 1 are co-prime so Batman can continue on
runway 1 without getting bombed)
2nd way: starting and covering distance of 1 at runway 1
and covering remaining distance at runway 2. i.e 1 -> 2
3rd way: starting and covering distance of 1 at runway 1
and covering remaining distance at runway 3. i.e 1 -> 3
similarly there are 4 more ways i.e 2 -> 1, 2 -> 3, 3 ->
1, 3 -> 2
we can't go from 2 -> 2 and 3 -> 3 as per given rules.
```
### Brute force
- Generate all permutations of 1,...,B of size A.
- Check if all the consicutive elements are co-prime. Count all such permutations.
- Time Complexity: B^A.
### First Approach
- It should be clear from the question that we need a graph of size B.
- Let's apply dynamic programing on this graph.
- Let dp[i][k] be the number of ways to start at i and run a length of k.
- dp[i][1] = 1 for all i.
- $dp[i][k] = \sum_{j \in adj[i]}dp[j][k-1]$
**Code**
```C++
int gcd(int i, int j){
if(i>j) return gcd(j,i);
else if (i == 0) return j;
else{
int k = j%i;
return gcd(k, i);
}
}
bool coPrime(int i, int j){
return gcd(i,j) == 1;
}
void printArray(vector<vector<int>> adj){
for(int i = 0 ; i<adj.size(); ++i){
cout << i << ": " ;
for(auto cell: adj[i]){
cout << cell << " ";
}
cout << endl;
}
}
int Solution::solve(int A, int B) {
if(A == 0) return 0;
vector<vector<int>> adj(B);
for(int i = 0; i< B; ++i){
for(int j = i ; j<B; ++j){
if(coPrime(i+1,j+1)){
adj[i].push_back(j);
if(i!=j){
adj[j].push_back(i);
}
}
}
}
//printArray(adj);
vector<int> dp_old(B);
vector<int> dp_new(B);
for(int i = 0; i < B; ++i){
dp_new[i] = 1;
}
int mod = 1000000007;
for(int k = 2; k<=A; ++k){
dp_old = dp_new;
for(int i = 0; i< B; ++i){
dp_new[i] = 0;
for(auto j : adj[i]){
dp_new[i] += dp_old[j]%mod;
dp_new[i] %= mod;
}
}
}
int res= 0;
for(int i= 0; i<B; ++i){
res += dp_new[i]%mod;
res %= mod;
}
return res;
}
```
### Second Approach(Matrix Exponentiation)
- If we look at the adj matrix, $A$ and its powers, we find some nice patterns.
- $A^1[i][j]$ will be 1 if there is an edge between i and j.
- $A^2[i][j] = \sum_{k \in\{0,n-1\}}A^1[i][k]* A^1[k][j]$
- $A^2[i][j]$ will have number of paths of size two between i and j.
- $A^4[i][j] = \sum_{k \in\{0,n-1\}}A^2[i][k]* A^2[k][j]$
- $A^4[i][j]$ will have number of paths of size four between i and j.
- In general $A^n[i][j]$ will have number of paths of size n between i and j.
- If our track length is t, then $\sum_{i,j \in\{0,n-1\}}A^t[i][j]$ will be give us all the possible paths of length t.
**Code**
```C++
#define ll long long int
int mod = 1000000007;
int gcd(int i, int j){
if(i>j) return gcd(j,i);
else if (i == 0) return j;
else{
int k = j%i;
return gcd(k, i);
}
}
bool coPrime(int i, int j){
return gcd(i,j) == 1;
}
void printArray(vector<vector<ll>> adj){
for(int i = 0 ; i<adj.size(); ++i){
cout << i << ": " ;
for(auto cell: adj[i]){
cout << cell << " ";
}
cout << endl;
}
}
void copy(vector<vector<ll>> &A, vector<vector<ll>> &B){
int n = A.size();
for(int i= 0; i<n ; ++i){
for(int j = 0; j<n ;++j){
B[i][j] = A[i][j];
}
}
}
void square(vector<vector<ll>> &A){
int n = A.size();
vector<vector<ll>> temp(n, vector<ll>(n));
copy(A,temp);
for(int i = 0; i<n ; ++i){
for(int j = 0; j<n ;++j){
A[i][j] = 0;
for(int k = 0; k<n; ++k){
A[i][j] = (A[i][j]%mod + ((temp[i][k]%mod)*(temp[k][j]%mod))%mod)%mod;
}
}
}
}
void multiply(vector<vector<ll>> &A, vector<vector<ll>> &B){
int n = A.size();
vector<vector<ll>> temp(n, vector<ll>(n));
copy(A,temp);
for(int i = 0; i<n ; ++i){
for(int j = 0; j<n ;++j){
A[i][j] = 0;
for(int k = 0; k<n; ++k){
A[i][j] = (A[i][j]%mod + ((temp[i][k]%mod)*(B[k][j]%mod))%mod)%mod;
}
}
}
}
void print(vector<vector<ll>> A){
cout << "-------------" << endl;
for(auto row: A){
for(auto cell: row){
cout << cell << " " ;
}
cout << endl;
}
}
void pow_matrix(vector<vector<ll>> &adj,int A, vector<vector<ll>> &orignal){
//print(adj);
//cout << A << endl;
if(A == 1) return;
int n = adj.size();
pow_matrix(adj, A/2, orignal);
square(adj);
if(A%2 == 1){
multiply(adj, orignal);
}
}
int Solution::solve(int A, int B) {
if(A == 0) return 0;
if(A == 1) return B;
vector<vector<ll> > adj(B, vector<ll> (B,0));
for(int i = 0; i< B; ++i){
for(int j = 0 ; j<B; ++j){
adj[i][j] = (coPrime(i+1, j+1))? 1: 0;
}
}
int n = B;
vector<vector<ll>> identity(n, vector<ll>(n,0));
copy(adj,identity);
pow_matrix(adj, A-1, identity);
long long int sum = 0;
for(int i= 0; i<B; ++i){
for(int j = 0; j<B; ++j){
sum = (sum%mod + adj[i][j]%mod)%mod;
sum %= mod;
}
}
return (int)sum;
}
```
## Subarray Transformations
### Problem Statement
Given an array A of size N **(1-indexed)** with all elements **initially 0**. You have to perform T transformations and return the **final** value of array.
Each transformation is of the form Xi , Yi.
In the ith transformation do the following operation Yi times,
**Subarray from index 1 to Xi is taken and choose the cell having minimum value and if there are many cells with same minimum value then choose cell having minimum index. Add 1 to the chosen cell.**
**Input**
```
2D array with 1st transformation as (array[0][0],
array[0][1]),...Tth transformation as (array[T - 1][0],
array[T - 1][1]).
```
**Output**
```
Return array of length N with arr[0] with value of 1st
element,... arr[N - 1] with value of Nth element.
```
**Constraints**
```C++
1 <= N <= 1000
0 <= T <= 10000
1 <= Xi <= N
1 <= Yi <= 100000
```
### Brute Force
- We can find the minimum cell in $O(X)$.
- In every step we have to increase it by one $Y$ times. This will in total take $O(X* Y)$.
- There are $T$ such updates. Thus it will take $O(X* Y* T)$ time.
- That will be $O(10^{12})$ it will give TLE.
- We are doing repetative work while increasing the minimum.
### Hints
- Observation: All nodes will be in non-increasing order.
- To find patterns in questions like these it is advisable to do a dry run on an small array.
- Initially, the array is all zeros. Let it be $[0,0,0,0,0]$
- X = 3, Y = 7
- $3,2,2,0,0$
- X = 5, Y = 6
- $3,2,2,2,2$, | Y = 2
- $3,3,3,2,2$, | Y = 0
- In first case we filled all nodes till $X$ by $Y/X$. And added 1 in $Y%X$ nodes.
- In second case we filled all nodes after 2 to level of 2. And then filled remaining $Y$ after 3.
- So, we will have two nodes $i,j$ such that if we fill all nodes after j the gain will be less than or equal to $Y$. And if we fill all nodes after i to level of i the gain will be greater than $Y$
- Here
- $i<j$
- $A[i] > A[i+1]$
- $A[j] > A[j+1]$
- We fill all the nodes after j to level of j. And fill nodes after $i$ like the first case.
### Code
```C++
bool isValid(vector<long long> psum, int i, int X, int Y, int h){
long long sum = psum[X] - psum[i];
return h*(X-i) - sum <= Y;
}
void update(vector<int> &array, int X, int Y){
int n = array.size();
vector<long long> psum(n,0);
psum[0] = array[0];
for(int i=1; i<n; ++i){
psum[i] += psum[i-1] + array[i];
}
int h;
for(int i = 0; i<=X; ++i){
h = array[i];
if(i<X && array[i] != array[i+1] && isValid(psum, i, X, Y, h)){
for(int j = i+1; j <= X; ++j){
Y -= h-array[j];
array[j] = h;
}
break;
}
}
int idx = 0;
while(array[idx] != h){
++idx;
}
int layers = Y/(X-idx+1);
int remaining = Y%(X-idx+1);
for(int i = idx ; i <= X; ++i){
array[i] += layers;
Y -= layers;
if(remaining > 0){
array[i]++;
Y--;
remaining--;
}
}
return;
}
vector<int> Solution::solve(int A, vector<vector<int> > &B) {
vector<int> array(A,0);
for(auto b : B){
update(array, b[0]-1, b[1]);
}
return array;
}
```
### Time Complexity
- Since we are running a loop of size $O(X)$ twice for every update, $O(X* T)$.
## Sum of Inversions
### Problem Statement
Consider a random permutation P of numbers [1, 2, .., N]. This permutation is called special if there is no element P[i] in P such that **P[i] = i+1** (Consider 0 based indexing). In other words, a permutation is special if it is a derangement (no number is at its "natural" (ordered) place).
Given a number N, find the sum of inversions in all the special permutations of numbers [1, 2, ..., N] modulo **1000000007**. An inversion in an array P is a pair P[i], P[j] such that P[i] > P[j] and i<j.
**Constraints:**
1 <= N <= 20
**Example:**
```C++
Input:
N = 3
Output:
4
Explanation:
For N=3, special permutations are [3,1,2] and [2,3,1]
Number of inversions in [3,1,2] = 2 ( (3,1) and (3,2) )
Number of inversions in [2,3,1] = 2 ( (3,1) and (2,1) )
Thus, sum of inversions = 2+2 = 4.
```
-----------
### Brute Force
- We can create all the permutations.
- Check if they are derangements.
- And find inversions in them.
- This will take $O(n!* n\log{n})$ time.
### Hints
- When ever the brute force is of the order $n!$. Try to think of bit masking dp.
- In bit masking we represented the subset of a set of size n by a n-digit binary number.
- The benefit of this representation is that we can use that number as key in a hash map to store information about perticular sets.
- In this problem, the information that we want to store is the number of inverstions in all the special permutations of a given subset. We also need to store the number of special permutations of every given subset.
- Set bits in mask would be arranged at positions [idx, idx+1, ...., n]
- Here $ids = n - unset_bit + 1$
```C++
int cnt = setbits_count(mask, n); //no. of set bits in mask
int idx = n-cnt+1; //set bits in mask would be arranged at positions [idx, idx+1, ...., n]
ll rank = 0;
for(int i=0; i<n; i++){
if(mask & (1<<i) ){ //if number i+1 is yet to be arranged
if(idx != i+1){ //according to our rule, a number cannot be at its original index
node temp = util(mask^(1<<i), n); //arrange the number (i+1) and calculate the ans for resulting mask
dp[mask].ans = (dp[mask].ans +
(temp.ans + ((temp.perm)*rank)%mod)%mod)%mod;
dp[mask].perm = (dp[mask].perm + temp.perm)%mod;
}
//rank = no. of numbers less than (i+1) in the mask
//for mask 11010 -> rank in iteration i=3 in for loop is 1 which means
// there is 1 number in the mask less than 4 (and that number is 2 in this case)
rank += 1;
}
}
```
### Hints on Website
This type of problems requires a special DP formulation known as Bitmask DP. Those who are not familiar with the concept are advised to Google it before proceeding further.
Consider the following DP formulation:
mask = bitmask where i-th set bit from the left means number i is yet to be used in generating a special permutation.
e.g.: mask = 5 => mask = 101 (binary) => Current permutation 2 _ _. Use numbers [1,3] to fill the blanks in the current permutation.
cnt = no. of unset bits in mask (mask = 5 => mask = 101 (binary) => no. of unset bits = 1)
dp[mask] = sum of inversions of all the special permutations that can be generated using the numbers corresponding to set bits in mask such that the numbers should be arranged at positions [cnt+1, cnt+2, .., N]
e.g.:
mask = 101
One number is already fixed at position 1 and that number is 2. Permutation generated till this point is 2 _ _. Now we have to arrange the remaining numbers [1,3] at blank positions and form a special permutation.
Recursion tree for N = 3 looks like following:
```
111
/ | \
011(1__) 101(2__) 110(3__)
/ \ / \
001 100 100 010
(21_) (23_) (32_) (31_)
```
Here, 011 at level 2 in the tree is not extended further as it is not a valid permutation (011 corresponds to permutation 1 _ _ and 1 cannot be at its correct position according to our rule of special permutations). Similarly "100" (child of "110" in level 3) is also not a valid permutation as that corresponds to permutation 32_.
This type of formulation will require us to ignore the branches of tree that form a non-valid permutation and consider those which forms a valid permutation. Now, the only challenge is to count the sum of inversions at every node of the tree. This is left as an exercise to the reader. Coding part is very easy once you have thought of a way to augment the recursion tree to store necessary information.
Time complexity of this approach would be O(C*N*(2^N)) which is much less than O(N!).
For any given N, our answer is simply dp[(1<<N)-1].
For N=3, our answer is dp[7] ( 7 = "111" in binary)
**Code**
```C++
#define mod 1000000007
#define maxn 20
#define ll long long
//Node to store the information of a state in dp
struct node{
ll perm;
ll ans;
bool vis;
node(): perm(0), ans(0), vis(0){}
}dp[1<<maxn];
//count the number of set bits in mask
int setbits_count(int mask, const int n){
int cnt = 0;
for(int i=0; i<n; i++){
if(mask & (1<<i)) cnt++;
}
return cnt;
}
node util(int mask, const int n){
//Check if this subproblem is already solved
if(dp[mask].vis != 0) return dp[mask];
//base case
if(mask == 0){
dp[mask].perm = 1;
dp[mask].vis = 1;
return dp[mask];
}
int cnt = setbits_count(mask, n); //no. of set bits in mask
int idx = n-cnt+1; //set bits in mask would be arranged at positions [idx, idx+1, ...., n]
ll rank = 0;
for(int i=0; i<n; i++){
if(mask & (1<<i) ){ //if number i+1 is yet to be arranged
if(idx != i+1){ //according to our rule, a number cannot be at its original index
node temp = util(mask^(1<<i), n); //arrange the number (i+1) and calculate the ans for resulting mask
dp[mask].ans = (dp[mask].ans + (temp.ans + ((temp.perm)*rank)%mod)%mod)%mod;
dp[mask].perm = (dp[mask].perm + temp.perm)%mod;
}
//rank = no. of numbers less than (i+1) in the mask
//for mask 11010 -> rank in iteration i=3 in for loop is 1 which means
// there is 1 number in the mask less than 4 (and that number is 2 in this case)
rank += 1;
}
}
dp[mask].vis = 1;
return dp[mask];
}
int Solution::solve(int n){
int mask = (1<<n) - 1; //initial mask --> 111...1 "n ones"
for(int i=0; i< (1<<n); i++){
dp[i].ans = 0;
dp[i].perm = 0;
dp[i].vis = 0;
}
return util(mask , n).ans;
}
```
### Dry Run
- A = 3
- 100 0 0
001 0 1
101 1 1
010 0 1
011 0 1
111 4 2
- 111 4 2
- 101 1 1
- 100 0 0
- 001 0 1
- 011 0 1
- 010 0 1
### Time Complexity
- $O(n* 2^n)$

View File

@ -0,0 +1,284 @@
# Miscelleneous Problems 14
## Valuable Nodes
### Problem Statement
Given a tree T containing N nodes numbered [1,2, ..., N] rooted at node 1. Each node has a value associated with it. You need to choose some of the nodes from the tree such that the sum of values of the chosen nodes is maximum possible. Moreover, if you have chosen a node V you cannot choose any of its children or grand children.
In simple words, you have to choose a subset of nodes such that no two nodes in the chosen set have a parent-child relation or grandfather-grandchild relation between them.
**Constraints:**
1 <= N <= 500,000
1 <= value of node <= 10,000
**Input:**
```
vector<int> A : A[i] --> Parent of node number i+1.
(A[2] = 1 means parent of node number 3 is 1).
vector<int> B : value[i] --> value associated with
node number i+1.
Note: Parent of node number 1 is 0 (A[0] = 0).
```
**Output:**
A number containing the maximum possible sum.
`(As the answer can be large, output the answer modulo 1000000007)`
**Example:**
```
Input:
A : [0, 1, 1, 1, 3, 3, 6, 6]
B: [1, 2, 3, 4, 5, 100, 7, 8]
Output:
111
Node number 2, 4, 5 and 6 are chosen. Sum = 2 + 4 + 5 + 100 = 111
```
### Brute Force
- The absolute brute force would be to take every subset.
- Check if it contains a child-parent or grandchild-grandparent relationship.
- Maximize the sum of values among these subsets.
### Hints
- Can we optimize the above brute force?
- We can select the node only if its child and grandchild are not selected.
- Can we reduce this problem to an array problem? That array problem will look as follows:
- You are given an array. There is a value stored at every cell. You need to find a subset with highest value sum. If you include A[i] into the set, you cannot include A[i-2], A[i-1], A[i+1], and A[i+2] into the set.
- The above problem can be solved using Dynamic Programming.
- We can store, for all index i, the maximum value of a valid subset of A[0..i].
- $dp[i] = max(dp[i-3]+A[i], dp[i-1])$
- We just look at $dp[i-3]$ and $dp[i-1]$ as $dp[i-2]$ is already included in $dp[i-1]$.
- Can we apply a similar approach to our tree problem?
### Code
```C++
#define ll long long int
int mod = 1000000007;
int getMaxDP(int node, vector<vector<int>> &child, vector<vector<int>> &ggchild, vector<int> &dp, vector<int> &value){
if(dp[node] != -1) return dp[node];
int first = 0, second = 0;
first = value[node]%mod;
for(auto ggc: ggchild[node]){
first = (first%mod + getMaxDP(ggc,child,ggchild,dp,value)%mod)%mod;
}
for(auto c: child[node]){
second = (second%mod + getMaxDP(c,child,ggchild,dp,value)%mod)%mod;
}
return max(first, second);
}
int Solution::solve(vector<int> &A, vector<int> &B) {
int n = A.size();
vector<vector<int>> adj(n);
vector<vector<int>> ggchild(n);
vector<int> dp(n,-1);
for(int i = 1; i<n; ++i){
adj[A[i]-1].push_back(i);
}
for(int i = 0; i<n; ++i){
for(auto c: adj[i]){
for(auto gc: adj[c]){
for(auto ggc: adj[gc]){
ggchild[i].push_back(ggc);
}
}
}
}
return getMaxDP(0,adj,ggchild,dp,B);
}
```
### Time Complexity
- Since we are calculating every dp only once the time complexity will be $O(E+V)$. Since it is a tree the time complexity will be $O(n)$.
### Dry Run
```C++
A : [0, 1, 1, 1, 3, 3, 6, 6]
B: [1, 2, 3, 4, 5, 100, 7, 8]
Children:
1: 2,3,4
2:
3: 5, 6
4:
5:
6: 7, 8
7:
8:
Great Grand Children
1: 7,8
2:
3:
4:
5:
6:
7:
8:
DP:
1: max(DP(2)+DP(3)+DP(4), B(1)+DP(7)+DP(8))
= max(2+105+4, 1+7+8) = 111
2: B(2) = 2
3: max(DP(5) + DP(6), B(3)) = max(100+5, 3) = 105
4: B(4) = 4
5: B(5) = 5
6: max(DP(7)+DP(8), B(6)) = max(7+8, 100) = 100
7: B(7) = 7
8: B(8) = 8
```
## String Rotation
### Problem Statement
Give a string S find lexicographically smallest string possible after circular rotation.
**Lexicographically smallest**: First string in dictionary order.
**Circular rotation**: Pushing the last character to the start.
**Input Format**
```
Argument 1: Length of the String
Argument 2: Given string
```
**Constraint**
```
0 < |S| <= 5000
```
**Sample Input 1**
```
BCABDADAB
```
**Sample Output 1**
```
ABBCABDAD
```
### Brute Force
- Consider all rotations and minimize over all of them.
### Hints
- This is a simple question included to encourage all of you to solve at least one problem.
- So, Go ahead and solve this question.
### Code
```C++
string Solution::solve(int A, string B) {
string doubleB = B + B;
set<string> s;
for(int i = 0; i < A; ++i){
s.insert(doubleB.substr(i,A));
}
return *s.begin();
}
```
### Time Complexity
- Each string comparision may take $O(n)$ time. Here, $n$ is the length of string.
- We have to compare strings $O(n)$ times. Thus the total time complexity will be $O(n^2)$.
- If we use a set, the time complexity will be $O(n^2\log{n})$. This is because insertion in set will take $O(n\log{n})$ time.
## Ways to Arrange Two Objects
### Problem Statement
You are given two types of objects : A and B. There is an infinite supply of both the type of objects .
All the objects of type A are identical and same is the case with all the objects of type B.
Given two integers N and L, find the number of ways in which you can arrange the N objects such that you don't have L or more
consecutive objects of type A together.
**Constraints:**
```
1 < N < 100001
1 < L < 100001
1 < N*L < 100001
```
**Input Format**
```
Input consists on one line containing the value of N and L.
```
**Output Format**
```
Return number of ways modulo 10^9 + 7
```
**Example:**
```
Input:4 2
Output: 8
Explanation:
{B,B,B,B}
{B,B,B,A}
{B,B,A,B}
{B,A,B,B}
{A,B,B,B}
{A,B,A,B}
{A,B,B,A}
{B,A,B,A}
```
### Brute Force
- We can consider all the possible arrangements of A and B.
- For each arrangement, we can check if there are L consicutive A's. We can neglect those arrangements and count others.
- This approach will take $O(n * 2^n)$ time.
### Hints
- We can neglact some arrangements even before making them if at each i we keep count of consecutive A's ending at i.
- Suppose there are L-1 A's ending at i. For example L = 3 and N = 6 and i = 3
- ${B, A, A}$ now on the next step we can not include A.
- Can we memoize these states in dp?
### Solution
- Dp state: dp[i][j] number of arrangements of A and B of length i with j consicutive A's towards the end.
- $dp[i][0]=\sum_{k\in{[0,L-1]}}dp[i-1][k]$
- $dp[i][j]_{j>0} = dp[i-1][j-1]$
### Code
```C++
int mod = 1000000007;
int Solution::solve(int A, int B) {
vector<vector<int>> dp(A+1, vector<int>(B,0));
dp[0][0] = 1;
for(int i = 1; i <= A; ++i){
for(int j = 0; j< B; ++j){
if(j == 0){
int val = 0;
for(int k = 0; k<B; ++k){
val = (val%mod + dp[i-1][k]%mod)%mod;
}
dp[i][j] = val;
}else{
dp[i][j] = dp[i-1][j-1];
}
}
}
int res = 0;
for(int k=0; k < B; ++k){
res = (res%mod + dp[A][k]%mod)%mod;
}
return res;
}
```
### Time Complexity
- It takes $O(1)$ time to calculate most of the dp states. There are $O(N)$ corresponding to $dp[i][0]$ that will take $O(L)$ time.
- There are $O(N* L)$ dp states. Thus the time complexity will be $O(N* L)$.
### Dry Run
N = 4, L = 2
|j->|0|1|
|:--|:--|:--|
|i = 0|1|0|
|1|1|1|
|2|2|1|
|3|3|2|
|4|5|3|
|Answer| 8||

View File

@ -0,0 +1,480 @@
# Miscelleneous Problems 15
## Bits and Bytes
### Problem Statement
You are given a binary string **S**.
You process it through a series of operations starting from the left where:
1) In the first operation, you remove the first bit of the number and append it to the right.
2) In the second operation, you remove the first 2 bits of the processed string one by one and append them to the right.
3) In the third operation, you now remove the first 3 bits of the new string one by one and append them to the right.
4) In the ith operation, you remove the first i bits of the new string one by one and append them to the right.
You have to find the minimum number of operations it takes to get back the original string.
Number of operations cannot be 0.
**Constraints:**
```
1 <= length of S <= 10^5
```
**Input:**
```
S : Binary string
```
**Output:**
```
Minimum number of operations to get back the
original string.
```
**Example:**
```
Input:
S: 111
Output:
1
In the first operation, the leftmost bit (1)
gets appended to the end of the string, and you
get the same string as the original, hence
answer is 1.
Input:
S: 101
Output:
2
In the first operation, the leftmost bit (1)
gets appended to the end of the string, and you
get the string 011.
In the second operation, the 2 leftmost bits get
appended to the end (011 => 110 => 101), we get
the same string as the original, hence answer is
2.
```
### Brute Force
- For every i from 1 to $\infty$, We can rotate the string by i digits and check if the new string is same as the original string.
- Time Complexity, We may run into an infinity loop.
- Suppose we can be sure that we will get our result in $O(n)$. For every i we will need $O(n)$ time. So, the total time will be $O(n^2)$.
### Hints
- We can see that by $i^{th}$ operation we will have rotated $\frac{i*(i+1)}{2}$ times. Let's call this $T_i$.
- If for some $i$, $T_i$ is divisible by $len(s)$, we can say we will definetely get our string back.
- For $i = 2* len(s)-1$, $T_i$ will obviously be divisible by $len(s)$.
- So, we can run a loop from $1$ to $2* len(s) -1$ on $i$. And check if $T_i$ will be divisible by $len(s)$ or not.
- This will run in $O(n)$ time.
- Will it give the smallest such i?
- The string may have a pattern repeating over and over again. For example : $s=101101101$, answer will be $2$.
- Can we find the length of the shortest repeating sequence? We can use KMP algorithm to do that.
- What will be the lps of above string? Answer: $LPS = [001123456]$.
- If $len(s)-LPS[len(s)-1]$ divides $len(s)$, $len(s)-LPS[len(s)-1]$ is the length of the repeating sequence.
- Now, we have to match $T_i$ with length of repeating pattern if there is a repeating pattern.
### Code
```C++
typedef long long ll;
ll minLEN(string s,ll lps[]){
lps[0]=0;
ll len=0;
ll p=1;
while(p<s.length()){
if(s[p]==s[len]){
len++;
lps[p]=len;
p++;
}else{
if(len!=0){
len=lps[len-1];
}else{
lps[p]=0;
p++;
}
}
}
len=lps[s.length()-1];
if(s.length()%(s.length()-len)==0){
return s.length()-len;
}else return s.length();
}
int Solution::minOperations(string A) {
ll lps[200003];
ll len=minLEN(A,lps);
ll ans;
for(ll i=1;;i++){
if((i*(i+1)/2)%len==0){
ans=i;
break;
}
}
return ans;
}
```
### Time Complexity
- $i$ ranges from $1$ to $2* len(s)$ in worst case. For each i we do constant amount of work. Thus the time complexity will be $O(n)$.
- KMP will take $O(n)$ additional time.
### Dry Run
```
s = 100100100
lps = [0,0,0,1,2,3,4,5,6]
length we need = 9-6 = 3
i = 2 , T_i = 3
answer = 2
```
## Conditional Swaps
### Problem Statement
Given an array A consisting of every number from 1 to N arranged in a random order.
It is also possible to swap a particular element at index i with an element at index i+1 for a particular set of indices.
The indices for which these swaps are allowed are given in the form of a string S of 1's and 0's.
If the i'th position of a string has 1, then it is possible to swap the i'th element of index with the (i+1)'th element else it is not allowed.
There is no limit on the number of swaps allowed, that is, you can make any number of swaps (as long as they are valid).
Find if it is possible to arrange the array in ascending order using any amount of swaps.
**Constraints:**
```
1. 2 <= N <= 100000
2. String S contains n-1 characters and is
made up of only 0's and 1's.
```
**Input:**
Integer N (size of array) , array of containing elements from 1 to N in random order, string S made up of 1's and 0's
**Output:**
Return a string "YES" if it is possible to arrange array in ascending order, else return "NO".
**Example:**
Input:
```
N:6
Array:[1 2 5 3 4 6]
S:01010
```
Function return:
```
NO
```
### Brute Force
- We can try to run bubble sort or insertion sort on the array based on the string S.
- If in any step of bubble sort we encounter that we can not swap an element which needs to be swaped we output "NO". If we are able to sort the array, we output "YES".
- Time Complexity: $O(n^2)$.
### Hints
- Can we take element at position $i$ and bring it to position $j$ if there are $0's$ between $i$ and $j-1$? No.
- Numbers are between $1$ to $N$. So, we already know the exact position of every entry.
- Can we not just check if the current position of an element and its sorted position are swapable? Yes
- Can we use prefix sum to do the above in $O(1)$ time? Yes
### Code
```C++
typedef int ll;
string Solution::solve(int A, vector<int> &B, string C) {
ll n,use;
n=A;ll arr[n+1];
// cin>>use;
for(ll i=1;i<=n;i++)
{
arr[i]=B[i-1];
}
string s,ans;
s=C;
ll pref[n];
pref[1]=s[0]-'0';
for(ll i=2;i<n;i++)
{
pref[i]=pref[i-1]+s[i-1]-'0';
}
ll flag=0;
for(ll i=1;i<=n;i++)
{
ll temp=arr[i];
if(i<temp)
{
if(i==1)
{
if(pref[temp-1]==temp-i or i==temp)
continue;
else
{
ans="NO";
flag=1;
break;
}
}
else
{
if(pref[temp-1]-pref[i-1]==temp-i or i==temp)
continue;
else
{
ans="NO";
flag=1;
break;
}
}
}
else
{
if(temp==1)
{
if(pref[i-1]==i-temp or i==temp)
continue;
else
{
ans="NO";
flag=1;
break;
}
}
else
{
if(pref[i-1]-pref[temp-1]==i-temp or i==temp)
continue;
else
{
ans="NO";
flag=1;
break;
}
}
}
}
if(!flag)
ans="YES";
return ans;
}
```
### Time Complexity
- The above algorithm runs in $O(n)$ time.
### Dry Run
```
N:6
Array:[1 2 5 3 4 6]
S:01010
Sorted Position: [0 1 4 2 3 5]
Prefix Sum Array: [0 1 0 1 0]
```
|i|Sorted Position| Equal| Is it possible to Move|
|:--|:--|:--|:--|
|0|0|Yes|-|
|1|1|Yes|-|
|2|4|No|No|
|Break ||||
## Random Attendance
### Problem Statement
Dr. Dhruv is a superb professor of Mathematics. He is so lenient that he doesn't even take attendance. But his students are not so cooperative.
Frustrating of all aspects is that students have stopped attending classes of Dr. Dhruv. Dr. Dhruv is really disappointed and he has decided to start taking attendance. There are A students in his class. Ordinary professors take a roll call as [1, 2, 3, ..., A] but Dr. Dhruv is no ordinary man. He has come up with a different method of taking roll call. His method is as follows:
He has a list B of K random integers which means that he will call out only K students. He will first treat the numbers [1, 2, 3, .., A] as strings
["1", "2", "3", .., "A"]. Then he will sort this vector of strings in lexicographic order (see example below). Now, Dr. Dhruv will call the numbers
which are at B[i]-th (0 <= i < K) position in the sorted order (see example below).
Simply putting, if the sorted order is S, then he will call students in the order { S[B[0] - 1], S[B[1] - 1], ..., S[B[K-1] - 1] }. You need to output the numbers in the sequence that Dr. Dhruv will call.
Note: Dr. Dhruv needs this task to finish quickly and hence expected time complexity `O(K*log(A))`
**Constraints:**
```
1 <= K <= 1000 and K <= A
1 <= B[i] <= A (Elements of B may not be distinct,
i.e, he can call a student multiple times)
1 <= A <= 10^9 (Yes, Dr. Dhruv can teach
10^9 students at a time)
```
**Example:**
```
Input:
A = 12, B = [2, 5]
Output:
ans = [10, 2]
Sorted list S: ["1", "10", "11", "12",
"2", "3", "4", "5", ...., "9"]
ans = [2nd number, 5th number] = [10, 2]
```
### Brute Force
- We can create a list of strings S: ["1", "2","3","4"...,"A"].
- We can sort this list.
- And for every i store S[B[i]-1] in answer array.
- This approach will take $O(k\times n\log^2{n})$.
- This will give TLE.
### Hints
- Without creating S, can we calculate the number of elements starting with "1".
|Number Of Digits|Numbers|Total|
|:--|:--|:--|
|1|1|1|
|2|10,11, ... 19|11|
|3|100, 101, ... 199|111|
- For every digit we can calculate the number of elements starting with that digit.
- We can calculate this number for every position in the answer.
### Code
```C++
//Note: Two functions are defined just
//for the sake of understanding.
//function_one and function_two can be
//combined into one function using a flag variable
/*
function_two(n,k) computes the rest
of the digits of the kth required number.
*/
string function_two(string s, int k){
// Base case, first string is empty in this case
if(k==1) return "";
k-=1; //Don't consider empty string
int l = s.size();
int f = s[0]-'0';
int temp = stoi(string(l,'1')); // 1111111... l digits
//Case when length of s is 1
if(l==1) return to_string(k-1);
string rem = s.substr(1);
//Note that i here starts from 0
for(int i=0; i<10; i++){
//Here we calculate the number
//of numbers starting from i.
//There will be multiple cases
//to handle which becomes clear
//after a little thinking.
if(i == f) temp/=10;
int buffer = temp;
if(i == f) buffer += stoi(rem) + 1;
if(k > buffer){
k-=buffer;
continue;
}
if(i == f) return to_string(i) + function_two(rem, k);
return to_string(i) + function_two(to_string(9*(temp/10)), k);
}
}
/*
function_one(n,k) computes the first
digit of the kth required number.
function_one and function_two are
separate as 1st digit can't be zero whereas
rest of the digits can be zero.
*/
string function_one(string s, int k){
int l = s.size(); //length of the number
int f = s[0]-'0'; //first digit of the number
int temp = stoi(string(l,'1')); // 1111111... l digits
//Base case, only 1 digit number
if(l==1) return to_string(k);
//Utility string, used below in the for loop
string rem = s.substr(1);
//find the number of numbers say
//num starting from x (x <= i).
//if k > num, first digit is not i,
//else first digit is i.
//Note that i here starts from 1.
for(int i=1; i<10; i++){
//Here we calculate the number of
//numbers starting from i.
//There will be multiple cases
//to handle which becomes clear
//after a little thinking.
if(i == f) temp/=10;
int buffer = temp;
if(i == f) buffer += stoi(rem) + 1;
if(k > buffer){
k-=buffer;
continue;
}
if(i == f) return to_string(i) + function_two(rem, k);
return to_string(i) + function_two(to_string(9*(temp/10)), k);
}
}
vector<int> Solution::solve(int A,const vector<int> &B){
string str = to_string(A);
int m = B.size();
vector<int> ans(m);
//function_one(n,k) give kth
//number in the sorted order of strings ["1", "2", ..., "n"]
for(int i=0; i<m; i++)
ans[i] = stoi(function_one(str,B[i]));
return ans;
}
```
### Time Complexity
- This approach will work in $O(k \times \log{n})$. Because there are $O(\log{n})$ digits in A and every digit take $O(1)$ time.
### Dry Run
```
A : 5789
B : [ 1789]
```
|Place|Digits|Rank|Numbers with Digit|
|:--|:--|:--|:--|
|1|1|1789|1111|
|1|2|678|1111|
|2||||
|Empty will first element||||
|2|0|677|111|
|2|1|566|111|
|2|2|455|111|
|2|3|344|111|
|2|4|233|111|
|2|5|122|111|
|2|6|11|111|
|26||||
|3|0|10|11|
|260||||
|4|0|9|1|
|...||||
|4|8|1|1|
|2608||||

View File

@ -0,0 +1,366 @@
# Miscelleneous Problems 20
## Balls in Boxes
### Problem Statement
Given an array of integers **A** of size **N** and an another array of strings **B** of size **N**. Each string in **B** is binary and of exact size **10**.
There are some Boxes having following characterstics:-
```
A[i] represents the cost of ith Box.
One Box can contain atmost 10 different colored balls in it.
B[i][j] = '1' indicates that ith Box contains jth colored ball.
B[i][j] = '0' indicates that ith Box doesn't contains jth colored ball.
```
Find and return **minimum** amount of money needed to buy the boxes such that you have **maximum distinct colored balls** in the end.
**Input Format**
```
The first argument given is the integer array A.
The second argument given is the string array B.
```
**Output Format**
```
Return minimum amount of money needed to buy the boxes such that you have maximum distinct
colored balls in the end.
```
**Constraints**
```
1 <= N <= 10000
0 <= A[i] <= 10^9
B[i][j] = {'0' ,'1'}
```
**For Example**
```
Example Input 1:
A = [20, 10, 9]
B = ["0110001010",
"0111110000", "1111111111"]
Example Output 1:
9
Example Explanation 1:
As box 3 contains balls of all colors, buying only this box is sufficient.
Input 2:
A = [20, 10, 9]
B = ["0110001010",
"0111110001", "1111111110"]
Output 2:
19
```
### Brute Force
- We can consider all subsets of boxes. For each subset we can calculate the total number of distinct balls and total cost to buy.
- Now, we can find the minimum cost among all the subsets with maximum distint balls.
- This approach will take $O(2^A \times A)$
### Hints
- With the brute force we are taking subsets of boxes. Can we take subsets of balls?
- For a given subset of balls we have to find the minimum cost to get that subset using first i boxes.
- At a given dp state, we have two variables a mask and an index. Now, we have the choice either to take index'th box or not to take it.
- We can calculate the maximum possible distinct balls. Now, after running the loop if we find that the number of ones in the mask is less than maximum we can set that dp to be Infinity. This will make sure that we ignore all the cases where our 1-count will be less than max possible.
### Code
```C++
#include <iostream>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <set>
#define lli long long
#define MAX 10004
#define INF 10000000000000000LL
using namespace std;
int mx;
lli A[MAX];
int val[MAX];
bool vis[MAX][1024];
lli dp[MAX][1024];
int n;
void validate(string s)
{
int sz = (int)s.size();
assert(sz == 10);
for ( int i = 0; i < 10; i++ ) assert(s[i] == '0' || s[i] == '1');
}
lli f(int idx, int mask)
{
if ( idx == n ) {
if ( __builtin_popcount(mask) == mx ) return 0;
return INF;
}
if ( vis[idx][mask] ) return dp[idx][mask];
vis[idx][mask] = true;
lli ans = min(f(idx + 1, mask), A[idx] + f(idx + 1, mask | val[idx]));
dp[idx][mask] = ans;
return ans;
}
int main()
{
freopen("inp5.txt", "r", stdin);
freopen("out5.txt", "w", stdout);
string s;
set <int> distinctBalls;
cin >> n;
assert(n >= 1 && n <= 10000);
for ( int i = 0; i < n; i++ ) {
cin >> A[i];
cin >> s;
assert(A[i] >= 0 && A[i] <= 1000000000);
validate(s);
for ( int j = 0; j < 10; j++ ) {
if ( s[j] == '1' ) distinctBalls.insert(j), val[i] |= (1 << j);
}
}
mx = (int)distinctBalls.size();
cout << f(0, 0) << endl;
return 0;
}
```
### Time Complexity
- Since we are calculating the every dp state only once. The time complexity will be $O(n \times 2^{10})$.
### Dry Run
- Let's say we have only two colors.
- N = 3
- A = {5, 10, 20}
- B = {10, 01, 11}
|Mask|Index|Dp|Expression(min)|
|:--|:--|:--|:--|
|00|0|15 |dp[1][00],A[0](=5) + dp[1][10]|
|00|1|20 |dp[2][00],A[1](=10) + dp[2][01]|
|10|1|10 |dp[2][10],A[1](=10) + dp[2][11]|
|00|2|20 |dp[3][00],A[2](=20) + dp[3][11]|
|01|2|20 |dp[3][01],A[2](=20) + dp[3][11]|
|10|2|20 |dp[3][10],A[2](=20) + dp[3][11]|
|11|2|0 |dp[3][11],A[2](=20) + dp[3][11]|
|00|3|INF||
|01|3|INF||
|10|3|INF||
|11|3|0| |
## The Ghost Type
### Problem Statement
Gengar has got an integer **A**. Now using his ghostly powers, he can create the permutation from **1** to **A** of this given number.
Since, he's a special kind of Poke'mon, so he thinks he deserves special permutations. He wants to find the total number of special permutations of length **N**, consisting of the integers from **1** to **A**.
A permutation is called special if it satisfies following condition:
If **P<sub>x</sub> & P<sub>y</sub> == P<sub>x</sub>**, then **x** < **y**, where **x** and **y** are two distinct indices of permutation and **P** is the permutation itself. "**&**" denotes the bitwise and operation.
Help Gengar in finding the number of such permutations.
**Input Format:**
```
First and only argument of
input conatins a single integer A
```
**Output Format:**
Ouput a string denoting the answer.
**Constraints:**
1 <= A <= 20
**For Example:**
```
Example Input 1:
A = 3
Example Output 1:
2
Explanation 1:
Special Permutation are: [1, 2, 3] and [2, 1, 3]
Example Input 2:
A = 4
Example Output 2:
8
```
### Brute Force
- Given a permutation we can check in $O(n^2)$ time whether it is special or not.
- We can consider all the permutations of $1...A$. Then we can count special permutations.
- This approach will take $O(2^n \times n^2)$.
### Hints
- If we look at a subset of numbers which are already there in the permutation from $1...i$, we can choose the next number to include.
- Next element to include will be one whose all x's are included.
- Thus if we start from an empty subset, we can build the complete set in buttom up manner.
### Code
```C++
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define ll long long int
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define f first
#define mp make_pair
#define mod 1000000007
#define s second
#define pb push_back
vector<int>submask[22];
bool vis[1<<22];
ll dp[1<<22];
int N;
ll rec(int mask){
if(mask==(1<<(N+1))-2) return 1;
if(vis[mask]) return dp[mask];
vis[mask] = 1;
ll &ret = dp[mask];
ret=0;
int x;
for(int i=1;i<=N;i++){
if(!(mask&(1<<i))){
bool ok = true;
for(int j = 0; j < submask[i].size(); j++){
x = submask[i][j];
if(!(mask&(1 << x ))) ok=false;
}
if(ok){
ret += rec(mask|(1<<i));
}
}
}
return ret;
}
int main(){
for(int i=1;i<=20;i++){
for(int j=i-1;j>=1;j--){
if( (i&j)==j ) submask[i].pb(j);
}
}
cin >> N;
cout<<rec(0);
}
```
### Time Complexity
- We are running a loop of $O(n)$ for every mask. For every candidate we need to check with all its x's. That will also take $O(n)$ time.
- Thus the total time will be $O(n! \times 2^n)$.
### Dry Run
- N = 4
- Submask
- 1(001) : {}
- 2(010) : {}
- 3(011) : {1,2}
- Dp
|Mask|Expression|Dp Value|
|000|dp[001] + dp[010]|2|
|001|dp[011]|1|
|010|dp[011]|1|
|011|dp[111]|1|
|111| | 1|
## Micro and Lucky Tree
### Problem Statement
Micro purchased a tree having **A** nodes numbered from **1** to **A**. It is rooted at node numbered **1**. But unfortunately that tree turned out to be bad luck. After he purchased that tree, he lost his job and girlfriend. So he went to his astrologer friend Mike for help.
Mike told him to assign a value in the range **1** to **B** (inclusive) to each node making sure that luck factor of all leaf nodes is **1**. Luck factor of a leaf node **v** is defined as *gcd* of values of all nodes lying in path from root to **v** (inclusive). Now Micro wants to know how many ways are there to make his tree lucky. That's where Mike failed, so he asked for your help.
**Input Format:**
```
First argument of input is a integer A
Second argument of input is a integer B
Third argument of input is an integer array C of size A. where C[i] denote the parent of i+1 th
node. C[0] = 1
```
**Output Format:**
```
Return a single integer denoting
answer mod 1000000007
```
**Constraints:**
```
1 <= A <= 50000
1 <= M <= 30
1 <= C[i] <= A
```
**For Example:**
```
Example Input 1:
A = 3, B = 2, C = [1, 1, 1]
Example Output 1:
5
Explanation 1:
possible values of node1, node2,
node3 are:
(2, 1, 1)
(1, 1, 2)
(1, 2, 2)
(1, 1, 1)
(1, 2, 1)
Example Input 2:
A = 4, B = 3, C = [1, 3, 1, 3]
Example Output 2:
71
```
### Brute Force
- We can take all arrangements and test the conditions by doing a traversal on the tree. This will take $O(n)$ per arrangement.
- This approach will take $O(A^B \times A)$.
### Hints
- If we can calculate the number of arrangements possible, for a sub tree rooted at a given node, we can solve this question.
- All we need to know is the gcd of all the numbers till that node.
### Code
```Python
dfs(from, g)
{
if DP[from][g] != -1:
// If we have already computed the values we will just return it
return DP[from][g]
if node from is a leaf:
ret = 0
for i from 1 to m: // Trying all the possible values at leaf
if gcd(i, g) == 1: // and checking number of integers, i, assigned at leaf
ret = ret + 1 // such that gcd(i, j)=1
dp[from][g] = ret
return ret
ret = 0
for i from 1 to m: // Trying all the possible values at node i (from 1 to m)
g1 = gcd(i, g) // and compute the GCD of values of all nodes lying in path from 1 to i
ways = 1 // and pass it in the DFS call to children of i
for to = children of node from // Computing the value \(DP\) of the node
ways = (ways * dfs(to, g1)) // by multiplying the values of the children
ret = (ret + ways)
dp[from][g] = ret
return ret
}
```
### Time Complexity
- $O(A \times B)$.
### Dry Run
```
Tree:
1
/ \
2 3
```
B = 3
```
1 -> 9
2 -> 4
3 -> 4
---------
17
```