Given two arrays A[] and B[] of length N and M respectively. A[] represents the age of N friends and B[] contains M number of pairs in the form of (X → Y), which denotes X knows Y and vice-versa. Then your task is to output the count of all possible sequences of length N friends with the given condition If (X → Y) and AX< AY, then in the sequence AXmust appear before AY.
Note:
Since the number of sequences can be large, therefore use modulo 109+7.
If three people let say A, B and C are there. Where A → B and B → C, then A →C also hold true.
The person who is not known of any other person can appear anywhere in the sequence irrespective of its age.
It can be seen that 1, 2, 3 and 4 knows each other and their order of age is according to given constraints while 5th is unknown for all others and its order not matters in sequence. This these 5 will be the age sequences according to given constraints. Therefore, output is 5.
Input: N = 2, M = 1, A[] = {2, 2}, B[] = {{1 → 2}} Output: 2 Explanation: There will be 2 such age sequences possible: {A1, A2} and {A2, A1} . They both have same age and knows each other also. Therefore, there will be two sequences. Note that, if they don't know each other then also the sequences will be same as this case.
Approach: Implement the idea below to solve the problem
The problem is based on the Graph Theory and Combinatorics. The problem can be solved using concept of DFS and Factorial. In this problem, DFS is used to visit each node exactly once and calculate the number of ways to place each person in the sequence considering their friends who have already been placed. Factorials are used for counting sequences. It represents the number of ways to arrange N distinct items into a sequence, which is why it's used here.
The final result, which is the total number of sequences counted under the modulo 10^9+7.
Total Arrangements: There are N! ways to arrange all the ages. This comes from the basic principle of permutations in combinatorics, Maintaining Relative Order: The relative sorted ordering of ages of each connected component should be maintained. This means that for each connected component, we divide by X!, where X! is the number of elements in the ith connected component. This is because within each connected component, the elements can be arranged in X! ways, but these arrangements do not produce distinct sequences due to the ordering constraint of ages.
Equal Strengths: Some elements that have ages equal in a connected component can be arranged in Y! ways. Here, Y! is the number of equal ages in the ith connected component. These arrangements produce distinct sequences because the strength ordering constraint does not apply to elements with equal ages.
So, the total number of possible sequences is given by the formula:
(N!*Y!/X!)
Steps were taken to solve the problem:
Precompute Factorials: Initialize an array let say Fac[] to store the factorial of numbers up to 2e5. This will be used later for combinatorics calculations.
Graph Construction: Read the friendship pairs from B[] and construct an adjacency list representation of the graph let say Adj.
DFS and Calculation: For each node, If it has not been visited, perform a DFS starting from that node. During the DFS, keep track of the count of each value in a HashMap let say Map. After the DFS, calculate the result using factorials and modular arithmetic.
Results: Output the number of ways calculated using factorials.
Code to implement the approach:
C++
// C++ code for the above approach:#include<iostream>#include<unordered_map>#include<vector>usingnamespacestd;// Define the modulo constantconstlonglongmodulo=1000000007;// Function prototypeslonglongpower(longlonga,longlongb,longlongcurr_mod);voiddfs(inti,vector<vector<int>>&adj,vector<bool>&vis,vector<longlong>&ar,unordered_map<longlong,longlong>&hm);voidCount_sequences(intN,intM,vector<longlong>&A,vector<vector<int>>&B,vector<longlong>&fac);intmain(){// Precompute factorials up to 2e5vector<longlong>fac(200001,0);fac[0]=1;for(inti=1;i<=200000;i++)fac[i]=(fac[i-1]*i)%modulo;// Read the number of nodes and edgesintN=5;intM=5;vector<longlong>A={10,12,15,20,15};vector<vector<int>>B={{1,2},{2,3},{3,4},{4,2},{3,1}};// Function callCount_sequences(N,M,A,B,fac);return0;}// Function to output the// number of sequencesvoidCount_sequences(intN,intM,vector<longlong>&A,vector<vector<int>>&B,vector<longlong>&fac){// Initialize adjacency list,// visited array, and ar arrayvector<vector<int>>adj(N);// Visiting array created for DFSvector<bool>Vis(N,false);// Constructing the graphfor(inti=0;i<N;i++)adj[i]=vector<int>();// Creating adjacency listfor(inti=0;i<M;i++){intu=B[i][0]-1;intv=B[i][1]-1;adj[u].push_back(v);adj[v].push_back(u);}// Initialize result and xlonglongres=1;intx=0;// Perform DFS and calculate// result for each nodefor(inti=0;i<N;i++){if(!Vis[i]){unordered_map<longlong,longlong>Map;dfs(i,adj,Vis,A,Map);longlongmul=1,cn=0;for(constauto&set:Map){cn+=set.second;longlongxx=set.second;mul=(mul*fac[xx])%modulo;}intinn=static_cast<int>(cn);longlongy=fac[x+inn];longlongd1=(power(fac[x],modulo-2,modulo)*power(fac[inn],modulo-2,modulo))%modulo;longlongfraction=(y*d1)%modulo;res=(res*((fraction*mul)%modulo))%modulo;x+=inn;}}// Print the resultcout<<res<<endl;}// Function to calculate (a^b) mod curr_mod// using binary exponentiationlonglongpower(longlonga,longlongb,longlongcurr_mod){if(b==0)return1;longlongtemp=power(a,b/2,curr_mod)%curr_mod;if((b&1)==0)return(temp*temp)%curr_mod;elsereturn(((temp*temp)%curr_mod)*a)%curr_mod;}// DFS function to traverse the graph// and update HashMap and Visiting arrayvoiddfs(inti,vector<vector<int>>&adj,vector<bool>&vis,vector<longlong>&ar,unordered_map<longlong,longlong>&hm){vis[i]=true;hm[ar[i]]+=1;for(intit:adj[i]){if(!vis[it])dfs(it,adj,vis,ar,hm);}}
Java
// Java code to implement the approachimportjava.util.*;// Driver ClassclassGFG{// Define the modulo constantstaticlongmodulo=1000000007;// Driver Functionpublicstaticvoidmain(String[]args){// Precompute factorials up to 2e5longfac[]=newlong[(int)2e5+1];fac[0]=1;for(inti=1;i<=(int)2e5;i++)fac[i]=(fac[i-1]*i)%modulo;// Read the number of nodes and edgesintN=5;intM=5;longA[]={10,12,15,20,15};int[][]B={{1,2},{2,3},{3,4},{4,2},{3,1}};// Function callCount_sequences(N,M,A,B,fac);}// Method to output the number of sequencespublicstaticvoidCount_sequences(intN,intM,longA[],int[][]B,long[]fac){// Initialize adjacency list, visited array, and ar// arrayArrayList<ArrayList<Integer>>adj=newArrayList<>();// Visiting array created for DFSbooleanVis[]=newboolean[N];// Constructing the graphfor(inti=0;i<N;i++)adj.add(newArrayList<>());// Creating adjacncy listfor(inti=0;i<M;i++){intu=B[i][0]-1;intv=B[i][1]-1;adj.get(u).add(v);adj.get(v).add(u);}// Initialize result and xlongres=1;intx=0;// Perform DFS and calculate result for each nodefor(inti=0;i<N;i++){if(!Vis[i]){HashMap<Long,Long>Map=newHashMap<>();dfs(i,adj,Vis,A,Map);longmul=1,cn=0;for(Map.Entry<Long,Long>set:Map.entrySet()){cn+=set.getValue();longxx=set.getValue();mul=(mul*fac[(int)xx])%modulo;}intinn=(int)cn;longy=fac[x+inn];longd1=(power(fac[x],modulo-2,modulo)*power(fac[inn],modulo-2,modulo))%modulo;longfraction=(y*d1)%modulo;res=(res*((fraction*mul)%modulo))%modulo;x+=inn;}}// Print the resultSystem.out.println(res);}// Function to calculate (a^b) mod curr_mod using binary// exponentiationpublicstaticlongpower(longa,longb,longcurr_mod){if(b==0)return1;longtemp=power(a,b/2,curr_mod)%curr_mod;if((b&1)==0)return(temp*temp)%curr_mod;elsereturn(((temp*temp)%curr_mod)*a)%curr_mod;}// DFS function to traverse the graph and update HashMap// and Visiting arraypublicstaticvoiddfs(inti,ArrayList<ArrayList<Integer>>adj,booleanvis[],longar[],HashMap<Long,Long>hm){vis[i]=true;hm.put(ar[i],hm.getOrDefault(ar[i],0L)+1);for(intit:adj.get(i)){if(!vis[it])dfs(it,adj,vis,ar,hm);}}}
Python
# code by Flutterflymodulo=1000000007defmain():fac=[0]*(int(2e5)+1)fac[0]=1foriinrange(1,int(2e5)+1):fac[i]=(fac[i-1]*i)%moduloN=5M=5A=[10,12,15,20,15]B=[[1,2],[2,3],[3,4],[4,2],[3,1]]count_sequences(N,M,A,B,fac)defcount_sequences(N,M,A,B,fac):adj=[[]for_inrange(N)]Vis=[False]*Nforiinrange(M):u=B[i][0]-1v=B[i][1]-1adj[u].append(v)adj[v].append(u)res=1x=0foriinrange(N):ifnotVis[i]:Map={}dfs(i,adj,Vis,A,Map)mul=1cn=0forkey,valueinMap.items():cn+=valuexx=valuemul=(mul*fac[xx])%moduloinn=int(cn)y=fac[x+inn]d1=(power(fac[x],modulo-2,modulo)*power(fac[inn],modulo-2,modulo))%modulofraction=(y*d1)%modulores=(res*((fraction*mul)%modulo))%modulox+=innprint(res)defpower(a,b,curr_mod):ifb==0:return1temp=power(a,b//2,curr_mod)%curr_modifb%2==0:return(temp*temp)%curr_modelse:return(((temp*temp)%curr_mod)*a)%curr_moddefdfs(i,adj,vis,ar,hm):vis[i]=Truehm[ar[i]]=hm.get(ar[i],0)+1foritinadj[i]:ifnotvis[it]:dfs(it,adj,vis,ar,hm)main()
C#
//code by Flutterfly usingSystem;usingSystem.Collections.Generic;classGFG{staticlongmodulo=1000000007;publicstaticvoidMain(string[]args){long[]fac=newlong[(int)2e5+1];fac[0]=1;for(inti=1;i<=(int)2e5;i++)fac[i]=(fac[i-1]*i)%modulo;intN=5;intM=5;long[]A={10,12,15,20,15};int[][]B={newint[]{1,2},newint[]{2,3},newint[]{3,4},newint[]{4,2},newint[]{3,1}};Count_sequences(N,M,A,B,fac);}publicstaticvoidCount_sequences(intN,intM,long[]A,int[][]B,long[]fac){List<List<int>>adj=newList<List<int>>();bool[]Vis=newbool[N];for(inti=0;i<N;i++)adj.Add(newList<int>());for(inti=0;i<M;i++){intu=B[i][0]-1;intv=B[i][1]-1;adj[u].Add(v);adj[v].Add(u);}longres=1;intx=0;for(inti=0;i<N;i++){if(!Vis[i]){Dictionary<long,long>Map=newDictionary<long,long>();dfs(i,adj,Vis,A,Map);longmul=1,cn=0;foreach(KeyValuePair<long,long>setinMap){cn+=set.Value;longxx=set.Value;mul=(mul*fac[(int)xx])%modulo;}intinn=(int)cn;longy=fac[x+inn];longd1=(power(fac[x],modulo-2,modulo)*power(fac[inn],modulo-2,modulo))%modulo;longfraction=(y*d1)%modulo;res=(res*((fraction*mul)%modulo))%modulo;x+=inn;}}Console.WriteLine(res);}publicstaticlongpower(longa,longb,longcurr_mod){if(b==0)return1;longtemp=power(a,b/2,curr_mod)%curr_mod;if((b&1)==0)return(temp*temp)%curr_mod;elsereturn(((temp*temp)%curr_mod)*a)%curr_mod;}publicstaticvoiddfs(inti,List<List<int>>adj,bool[]vis,long[]ar,Dictionary<long,long>hm){vis[i]=true;if(hm.ContainsKey(ar[i]))hm[ar[i]]++;elsehm[ar[i]]=1;foreach(intitinadj[i]){if(!vis[it])dfs(it,adj,vis,ar,hm);}}}
JavaScript
// JavaScript code for the above approach:// Function to calculate (a^b) mod curr_mod using binary exponentiationfunctionpower(a,b,curr_mod){if(b===0n)return1n;consttemp=power(a,b/2n,curr_mod)%curr_mod;if(b%2n===0n)return(temp*temp)%curr_mod;elsereturn(((temp*temp)%curr_mod)*a)%curr_mod;}// DFS function to traverse the graph and update HashMap and Visiting arrayfunctiondfs(i,adj,vis,ar,hm){vis[i]=true;hm[ar[i]]=(hm[ar[i]]||0n)+1n;for(constitofadj[i]){if(!vis[it])dfs(it,adj,vis,ar,hm);}}// Function to output the number of sequencesfunctioncountSequences(N,M,A,B,fac){// Initialize adjacency list, visited array, and ar arrayconstadj=newArray(N).fill(null).map(()=>[]);// Visiting array created for DFSconstvis=newArray(N).fill(false);// Constructing the graphfor(leti=0;i<M;i++){constu=B[i][0]-1;constv=B[i][1]-1;adj[u].push(v);adj[v].push(u);}// Initialize result and xletres=1n;letx=0n;// Perform DFS and calculate result for each nodefor(leti=0;i<N;i++){if(!vis[i]){consthm={};dfs(i,adj,vis,A,hm);letmul=1n,cn=0n;for(constsetinhm){cn+=hm[set];constxx=hm[set];mul=(mul*fac[xx])%1000000007n;}constinn=cn;consty=fac[x+inn];constd1=(power(fac[x],1000000005n,1000000007n)*power(fac[inn],1000000005n,1000000007n))%1000000007n;constfraction=(y*d1)%1000000007n;res=(res*((fraction*mul)%1000000007n))%1000000007n;x+=inn;}}// Print the resultconsole.log(res.toString());}// Precompute factorials up to 2e5constfac=newArray(200001).fill(0n);fac[0]=1n;for(leti=1;i<=200000;i++)fac[i]=(fac[i-1]*BigInt(i))%1000000007n;// Read the number of nodes and edgesconstN=5;constM=5;constA=[10,12,15,20,15];constB=[[1,2],[2,3],[3,4],[4,2],[3,1]];// Function callcountSequences(N,M,A,B,fac);
Output
5
Time Complexity: O(N2), Where N is the number of nodes in the graph. This is because for each node, the code performs a depth-first search (DFS) which can visit each node in the graph, and for each node visited, it performs operations that are linear in the number of nodes.
Auxiliary Space: O(N),This is because it maintains an adjacency list representation of the graph, a visited array to keep track of visited nodes, and an array to store some values associated with each node are used. The HashMap used to keep track of counts during DFS also contributes to the space complexity, but its size is at most N, so it doesn’t change the overall space complexity.