Find the numbers of strings that can be formed after processing Q queries

Given a number N(1<=N<=2000)., The task is to find the number strings of size N that can be obtained after using characters from 'a' to 'z' and by processing the given q(1<=q<=200000) queries.

For each query given two integers L, R (0<=L<=R<=N) such that substring [L, R] of the generated string of size N must be a palindrome. The task is to process all queries and generate a string of size N such that the substrings of this string defined by all queries are palindrome.

The answer can be very large. So, output answer modulo 1000000007.

Note: 1-based indexing is considered for the string.

Examples:

Input : N = 3
query 1: (1, 2)
query 2: (2, 3)
Output : 26
Explanation : Substring 1 to 2 should be 
palindrome and substring 2 to 3 should be palindrome. so, all 
three characters should be same. so, we can obtain 26 such strings.

Input : N = 4
query 1: (1, 3)
query 2: (2, 4)
Output : 676
Explanation : substring 1 to 3 should be 
palindrome and substring 2 to 4 should be a palindrome. 
So, a first and third character should be the same and 
second and the fourth should be the same. So, we can 
obtain 26*26 such strings.

Approach : An efficient solution is to use union-find algorithm.

  • Find the mid-point of each range (query) and if there are many queries having the same mid-point then only retain that query whose length is max, i.e (where r – l is max).
  • This would have reduced the number of queries to 2*N at max since there is a 2*N number of mid-points in a string of length N.
  • Now for each query do union of element l with r, (l + 1) with (r – 1), (l + 2) with (r – 2) and so on. We do this because the character which would be put on the index l would be the same as the one we put on index r. Extending this logic to all queries we need to maintain disjoint-set data structure. So basically all the elements of one component of disjoint-set should have the same letter on them.
  • After processing all the queries, let the number of disjoint-set components be x, then the answer is 26^x
  • .

    Below is the implementation of the above approach :

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement above approach
  
#include <bits/stdc++.h>
using namespace std;
#define N 2005
#define mod (int)(1e9 + 7)
  
// To store the size of string and
// number of queries
int n, q;
  
// To store parent and rank of ith place
int par[N], Rank[N];
  
// To store maximum interval
map<int, int> m;
  
// Function for initialization
void initialize()
{
    for (int i = 0; i <= n; i++) {
        par[i] = i;
        Rank[i] = 0;
    }
}
  
// Function to find parent
int find(int x)
{
    if (par[x] != x)
        par[x] = find(par[x]);
  
    return par[x];
}
  
// Function to make union
void Union(int x, int y)
{
    int xpar = find(x);
    int ypar = find(y);
  
    if (Rank[xpar] < Rank[ypar])
        par[xpar] = ypar;
    else if (Rank[xpar] > Rank[ypar])
        par[ypar] = xpar;
    else {
        par[ypar] = xpar;
        Rank[xpar]++;
    }
}
  
// Power function to calculate a raised to m1
// under modulo 10000007
int power(long long a, long long m1)
{
    if (m1 == 0)
        return 1;
    else if (m1 == 1)
        return a;
    else if (m1 == 2)
        return (1LL * a * a) % mod;
    else if (m1 & 1)
        return (1LL * a * power(power(a, m1 / 2), 2)) % mod;
    else
        return power(power(a, m1 / 2), 2) % mod;
}
  
// Function to take maxmium interval
void query(int l, int r)
{
    m[l + r] = max(m[l + r], r);
}
  
// Function to find different possible strings
int possiblestrings()
{
    initialize();
  
    for (auto i = m.begin(); i != m.end(); i++) {
        int x = i->first - i->second;
        int y = i->second;
  
        // make union of all chracters which
        // are meant to be same
        while (x < y) {
            Union(x, y);
            x++;
            y--;
        }
    }
  
    // find number of different sets formed
    int ans = 0;
    for (int i = 1; i <= n; i++)
        if (par[i] == i)
            ans++;
  
    // return the required answer
    return power(26, ans) % mod;
}
  
// Driver Code
int main()
{
    n = 4;
  
    // queries
    query(1, 3);
    query(2, 4);
  
    cout << possiblestrings();
  
    return 0;
}

chevron_right


Python3

# Python3 program to implement above approach
N = 2005
mod = 10**9 + 7

# To store the size of string and
# number of queries
n, q = 0, 0

# To store parent and rank of ith place
par = [0 for i in range(N)]
Rank = [0 for i in range(N)]

# To store maximum interval
m = dict()

# Function for initialization
def initialize():

for i in range(n + 1):
Rank[i], par[i] = 0, i

# Function to find parent
def find(x):
if (par[x] != x):
par[x] = find(par[x])

return par[x]

# Function to make union
def Union(x, y):

xpar = find(x)
ypar = find(y)

if (Rank[xpar] < Rank[ypar]): par[xpar] = ypar elif (Rank[xpar] > Rank[ypar]):
par[ypar] = xpar
else:
par[ypar] = xpar
Rank[xpar] += 1

# Power function to calculate a raised to m1
# under modulo 10000007
def power(a, m1):

if (m1 == 0):
return 1
elif (m1 == 1):
return a
elif (m1 == 2):
return (a * a) % mod
elif (m1 & 1):
return (a * power(power(a, m1 // 2), 2)) % mod
else:
return power(power(a, m1 // 2), 2) % mod

# Function to take maxmium interval
def query(l, r):
if l + r in m.keys():
m[l + r] = max(m[l + r], r)
else:
m[l + r] = max(0, r)

# Function to find different possible strings
def possiblestrings():
initialize()

for i in m:
x = i – m[i]
y = m[i]

# make union of all chracters which
# are meant to be same
while (x < y): Union(x, y) x += 1 y -= 1 # find number of different sets formed ans = 0 for i in range(1, n + 1): if (par[i] == i): ans += 1 # return the required answer return power(26, ans) % mod # Driver Code n = 4 # queries query(1, 3) query(2, 4) print(possiblestrings()) # This code is contributed by Mohit Kumar [tabbyending]

Output:

676


My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : mohit kumar 29