Sereja and two strings

Description:

Sereja has a string A consisting of n lower case English letters. Sereja calls two strings X and Y each of length n similar if they can be made equal by applying the following operation at most once in each of them. Chose any two position i, j in the string (i can be equal to j too). Swap the characters at position i with character at position j. For example strings "abcd" and "acbd" are similar, strings "ab" and "ab" are similar, but strings "abcde" and "bcdea" are not similar. Note that strings "abc" and "cab" are also similar, as you can swap 'a' and 'c' in the first string to get "cba" and 'a' and 'b' in the second string to get "cba". Now Sereja is interested in finding number of ordered pairs of non similar strings X and Y such that they can be constructed from a given string A by permutation of its characters. As answer could be large, please output your answer modulo (109 + 7). Test Case 1 Input (stdin) 2 z abcd Expected Output 0 144 Test Case 2 Input (stdin) 7 eee kiei ccrr wee weok rrree abcd Expected Output 0 0 0 0 144 0 144

Program :

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.io.Writer;

import java.util.InputMismatchException;

 

 

 

 

public class TestClass {

 

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

InputReader in=new InputReader(System.in);

OutputWriter out =new OutputWriter(System.out);

long inversefacorail[]=new long [111111];

long facctorial[]=new long[111111];

facctorial[0]=1;

inversefacorail[0]=1;

int mod =1000000000+7;

for(int i=1;i<111111;i++){

facctorial[i]=facctorial[i-1]*i%mod;

long deno=modInverse(i, mod);

inversefacorail[i]=inversefacorail[i-1]*deno%mod;

}

int t=in.readInt();

while(t>0)

{

String s =in.readString();

long A[]=new long[26];

for(int i=0;i<s.length();i++){

A[s.charAt(i)-'a']++;

}

long p=facctorial[s.length()];

for(int i=0;i<26;i++){

p=p*inversefacorail[(int)A[i]]%mod;

}

long z=1;

for(int i=0;i<26;i++){

for(int j=i+1;j<26;j++){

z=(z+A[i]*A[j])%mod;

}

}

for(int i=0;i<26;i++){

for(int j=i+1;j<26;j++){

for(int k=j+1;k<26;k++){

z=(z+2*A[i]*A[j]*A[k])%mod;

}

}

}

for(int i=0;i<26;i++){

for(int j=i+1;j<26;j++){

for(int k=j+1;k<26;k++){

for(int l=k+1;l<26;l++){

z=(z+3*(A[i]*A[j]*A[k]%mod)*A[l])%mod;}

}

}

}

for(int j=0;j<26;j++){

for(int k=j+1;k<26;k++){

 

for(int i=0;i<26;i++){

if(i!=j&&k!=i)

z=(z+A[i]*(A[i]-1)*A[j]%mod*A[k])%mod;

}

}

}

for(int i=0;i<26;i++){

for(int j=i+1;j<26;j++){

z=(z+(A[i]*(A[i]-1))*A[j]%mod*((A[j]-1)*modInverse(4, mod)%mod))%mod;

}

}

long all=p*p%mod;

long sub=p*z%mod;

long ans=(all-sub)%mod;

if(ans<0)ans+=mod;

out.printLine(ans);

t--;

}

out.close();

}

static long pow(long a, long b, long MOD)

{

    long x = 1, y = a;

    while (b > 0)

    {

        if (b % 2 == 1)

        {

            x = (x * y);

            if (x > MOD)

                x %= MOD;

        }

        y = (y * y);

        if (y > MOD)

            y %= MOD;

        b /= 2;

    }

    return x;

}

 

static long modInverse(long a, long m)

{

    return pow(a, m - 2, m);

}

 

}

 

 

 

 

 

 

class InputReader {

 

private InputStream stream;

private byte[] buf = new byte[1024];

private int curChar;

private int numChars;

private SpaceCharFilter filter;

 

public InputReader(InputStream stream) {

this.stream = stream;

}

 

public int read() {

if (numChars == -1)

throw new InputMismatchException();

if (curChar >= numChars) {

curChar = 0;

try {

numChars = stream.read(buf);

} catch (IOException e) {

throw new InputMismatchException();

}

if (numChars <= 0)

return -1;

}

return buf[curChar++];

}

 

public int readInt() {

int c = read();

while (isSpaceChar(c))

c = read();

int sgn = 1;

if (c == '-') {

sgn = -1;

c = read();

}

int res = 0;

do {

if (c < '0' || c > '9')

throw new InputMismatchException();

res *= 10;

res += c - '0';

c = read();

} while (!isSpaceChar(c));

return res * sgn;

}

 

public String readString() {

int c = read();

while (isSpaceChar(c))

c = read();

StringBuilder res = new StringBuilder();

do {

res.appendCodePoint(c);

c = read();

} while (!isSpaceChar(c));

return res.toString();

}

 

public boolean isSpaceChar(int c) {

if (filter != null)

return filter.isSpaceChar(c);

return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;

}

 

public String next() {

return readString();

}

 

public interface SpaceCharFilter {

public boolean isSpaceChar(int ch);

}

}

 

class OutputWriter {

private final PrintWriter writer;

 

public OutputWriter(OutputStream outputStream) {

writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));

}

 

public OutputWriter(Writer writer) {

this.writer = new PrintWriter(writer);

}

 

public void print(Object...objects) {

for (int i = 0; i < objects.length; i++) {

if (i != 0)

writer.print(' ');

writer.print(objects[i]);

}

}

 

public void printLine(Object...objects) {

print(objects);

writer.println();

}

 

public void close() {

writer.close();

}

 

public void flush() {

writer.flush();

}

 

}

 

class IOUtils {

 

public static int[] readIntArray(InputReader in, int size) {

int[] array = new int[size];

for (int i = 0; i < size; i++)

array[i] = in.readInt();

return array;

}