RainX_69

Fermat Little Theorem , Anagrams

Dec 26th, 2022 (edited)
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.60 KB | Source Code | 0 0
  1. /*
  2. https://leetcode.com/problems/count-anagrams/
  3.  
  4. You are given a string s containing one or more words. Every consecutive pair of words is separated by a single space ' '.
  5.  
  6. A string t is an anagram of string s if the ith word of t is a permutation of the ith word of s.
  7.  
  8. For example, "acb dfe" is an anagram of "abc def", but "def cab" and "adc bef" are not.
  9. Return the number of distinct anagrams of s. Since the answer may be very large, return it modulo 109 + 7.
  10.  
  11.  
  12.  
  13. Example 1:
  14.  
  15. Input: s = "too hot"
  16. Output: 18
  17. Explanation: Some of the anagrams of the given string are "too hot", "oot hot", "oto toh", "too toh", and "too oht".
  18. Example 2:
  19.  
  20. Input: s = "aa"
  21. Output: 1
  22. Explanation: There is only one anagram possible for the given string.
  23.  
  24.  
  25. Constraints:
  26.  
  27. 1 <= s.length <= 10^5
  28. s consists of lowercase English letters and spaces ' '.
  29. There is single space between consecutive words.
  30. */
  31.  
  32. class Solution {
  33. public:
  34.     int MOD=1000000007;
  35.     int dp[100001];
  36.    
  37.     long long int binaryExponentiation(long long int x, int pow){
  38.         long long int res=1;
  39.         while(pow>0){
  40.             if(pow%2==0){
  41.                 x=(x*x)%MOD;
  42.                 pow/=2;
  43.             }
  44.             else{
  45.                 res=(res*x)%MOD;
  46.                 pow--;
  47.             }
  48.         }
  49.         return res;
  50.     }
  51.    
  52.     long long int factorial(int n){
  53.         if(n==1){
  54.             return 1;
  55.         }
  56.         if(dp[n]!=-1){
  57.             return dp[n];
  58.         }
  59.         return dp[n]=(n*factorial(n-1))%MOD;
  60.     }
  61.    
  62.     long long int Arrangements(vector<int> &freq){
  63.         int n=accumulate(freq.begin(),freq.end(),0);
  64.         long long int total=factorial(n);
  65.         for(int i=0;i<26;i++){
  66.             if(freq[i]==0){
  67.                 continue;
  68.             }
  69.             long long int Fx=factorial(freq[i]);
  70.             total=(total*binaryExponentiation(Fx,MOD-2))%MOD;
  71.         }
  72.         return total;
  73.     }
  74.    
  75.     int countAnagrams(string s) {
  76.         memset(dp,-1,sizeof(dp));
  77.         int n=s.size();
  78.         long long int res=1;
  79.         for(int i=0;i<n;i++){
  80.             vector<int> freq(26,0);
  81.             while(i<n && s[i]!=' '){
  82.                 freq[s[i]-'a']++;
  83.                 i++;
  84.             }
  85.             res=(res*Arrangements(freq))%MOD;
  86.         }
  87.         return res;
  88.     }
  89. };
  90.  
  91.  
  92. /*
  93. THOUGHT PROCESS-
  94.  
  95. Some important concepts links-
  96. https://drive.google.com/file/d/1ER7_yAp9u_nmcYGRRTnJVQFxVMojVwj4/view?usp=sharing
  97. https://drive.google.com/file/d/1-OfhISGw5tP7w7PsShR6WlTMM-i5X2Lq/view?usp=sharing
  98.  
  99. See, it is quite simple, you can easily find the total number of ways simply by multiplying the total distinct anagrams of each word.
  100. So in short, it is like
  101. long long res=1;
  102. for(int i=0;i<words.size();i++){  res=res * arrangements(word);  }
  103.  
  104. The real problem though, is not in just solving. But rather handling the modulo and power raised to a number.
  105.  
  106. Please go through the above google drive links before proceeding furthur.
  107.  
  108. So by now, you have realized getting the answer of a factorial is not that difficult, as we do simple MOD while multiplying, but remember since you do modulo operation, the general laws of division would not apply here because you are using modulo and modulo changes the actual answer if overflowing. So, simple a/b would not work and a is not correct a!, but (a! % mod), same goes for b!, and dividing these will result in wrong answer, and that is why to overcome this issue we use inverse factorial AKA FERMAT LITTLE THEOREM. And since fermat theorem needs us to do base-power calculation, so to speed it up, we use binary exponentiation
  109. */
Advertisement
Add Comment
Please, Sign In to add comment