Maximum Palindromes

  • + 0 comments

    import java.io.; import java.util.;

    class Result {

    private static final int MOD = 1000000007;
    private static int[][] prefixFreq;
    private static long[] fact;
    private static long[] invFact;
    
    public static void initialize(String s) {
        int n = s.length();
        prefixFreq = new int[n + 1][26];
    
        for (int i = 0; i < n; i++) {
            System.arraycopy(prefixFreq[i], 0, prefixFreq[i + 1], 0, 26);
            prefixFreq[i + 1][s.charAt(i) - 'a']++;
        }
    
        fact = new long[n + 1];
        invFact = new long[n + 1];
        fact[0] = invFact[0] = 1;
    
        for (int i = 1; i <= n; i++) {
            fact[i] = (fact[i - 1] * i) % MOD;
        }
    
        invFact[n] = modInverse(fact[n]);
        for (int i = n - 1; i >= 1; i--) {
            invFact[i] = (invFact[i + 1] * (i + 1)) % MOD;
        }
    }
    
    public static int answerQuery(int l, int r) {
        int[] freq = new int[26];
        for (int i = 0; i < 26; i++) {
            freq[i] = prefixFreq[r][i] - prefixFreq[l - 1][i];
        }
    
        int pairs = 0;
        int oddCount = 0;
        int[] halfFreq = new int[26];
    
        for (int i = 0; i < 26; i++) {
            halfFreq[i] = freq[i] / 2;
            pairs += halfFreq[i];
            if (freq[i] % 2 == 1) {
                oddCount++;
            }
        }
    
        long numerator = fact[pairs];
        long denominator = 1;
        for (int i = 0; i < 26; i++) {
            if (halfFreq[i] > 0) {
                denominator = (denominator * invFact[halfFreq[i]]) % MOD;
            }
        }
    
        long result = (numerator * denominator) % MOD;
        result = (result * Math.max(1, oddCount)) % MOD;
    
        return (int) result;
    }
    
    private static long modInverse(long x) {
        return modPow(x, MOD - 2);
    }
    
    private static long modPow(long base, long exp) {
        long result = 1;
        base %= MOD;
        while (exp > 0) {
            if ((exp & 1) == 1) {
                result = (result * base) % MOD;
            }
            base = (base * base) % MOD;
            exp >>= 1;
        }
        return result;
    }
    

    }

    public class Solution { public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

        String s = bufferedReader.readLine();
        Result.initialize(s);
    
        int q = Integer.parseInt(bufferedReader.readLine().trim());
    
        for (int qItr = 0; qItr < q; qItr++) {
            String[] input = bufferedReader.readLine().trim().split(" ");
            int l = Integer.parseInt(input[0]);
            int r = Integer.parseInt(input[1]);
    
            int result = Result.answerQuery(l, r);
            bufferedWriter.write(String.valueOf(result));
            bufferedWriter.newLine();
        }
    
        bufferedReader.close();
        bufferedWriter.close();
    }
    

    }