📌  相关文章
📜  查找处理Q查询后可以形成的字符串数

📅  最后修改于: 2021-05-06 20:30:02             🧑  作者: Mango

给定数字N (1 <= N <= 2000)。,任务是找到大小为N的数字字符串,该数字字符串可以在使用从’a’到’z’的字符并处理给定的q (1 < = q <= 200000)查询。

对于每个查询,给定两个整数L,R(0 <= L <= R <= N),以使生成的大小为N的字符串的子字符串[L,R]必须是回文。的任务是处理所有查询和生成大小的字符串N,使得由所有查询定义的该字符串的子串是回文。

答案可能非常大。因此,输出答案取模1000000007。

注意:字符串考虑从1开始的索引。

例子:

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.

方法:一种有效的解决方案是使用联合查找算法。

  • 找到每个范围(查询)的中点,如果有许多具有相同中点的查询,则仅保留长度最大的查询,即(其中r – l为最大)。
  • 由于长度为N的字符串中点数为2 * N,因此查询数量最多可以减少到2 * N。
  • 现在,对于每个查询,将元素l与r合并,将(l + 1)与(r – 1)合并,将(l + 2)与(r – 2)合并,依此类推。我们这样做是因为要放在索引l上的字符与我们要放在索引r上的字符相同。将此逻辑扩展到所有查询,我们需要维护不交集的数据结构。因此,基本上,不相交集的一个组成部分的所有元素上都应具有相同的字母。
  • 处理完所有查询后,让不交集的组件数为x,则答案为26 ^ x

    下面是上述方法的实现:

    C++
    // C++ program to implement above approach
      
    #include 
    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 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;
    }


    Java
    // Java program to implement above approach
    import java.util.*;
      
    class GFG 
    {
        static final int N = 2005;
        static final int mod = 1000000007;
      
        // To store the size of string and
        // number of queries
        static int n, q;
      
        // To store parent and rank of ith place
        static int[] par = new int[N], Rank = new int[N];
      
        // To store maximum interval
        static HashMap m = new HashMap<>();
      
        // Function for initialization
        static void initialize()
        {
            for (int i = 0; i <= n; i++)
            {
                par[i] = i;
                Rank[i] = 0;
            }
        }
      
        // Function to find parent
        static int find(int x)
        {
            if (par[x] != x)
                par[x] = find(par[x]);
      
            return par[x];
        }
      
        // Function to make union
        static 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
        static long power(long a, long m1) 
        {
            if (m1 == 0)
                return 1;
            else if (m1 == 1)
                return a;
            else if (m1 == 2)
                return (1L * a * a) % mod;
            else if (m1 % 2 == 1)
                return (1L * a * power(power(a, m1 / 2), 2)) % mod;
            else
                return power(power(a, m1 / 2), 2) % mod;
        }
      
        // Function to take maxmium interval
        static void query(int l, int r)
        {
            if (m.containsKey(l + r))
                m.put(l + r, Math.max(m.get(l + r), r));
            else
                m.put(l + r, r);
        }
      
        // Function to find different possible strings
        static long possiblestrings() 
        {
            initialize();
      
            for (Integer i : m.keySet())
            {
                int x = i - m.get(i);
                int y = m.get(i);
      
                // 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
        public static void main(String[] args) 
        {
            n = 4;
      
            // queries
            query(1, 3);
            query(2, 4);
      
            System.out.println(possiblestrings());
        }
    }
      
    // This code is contributed by
    // sanjeev2552


    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


    C#
    // C# program to implement above approach
    using System;
    using System.Collections.Generic; 
      
    class GFG{
          
    const int N = 2005;
    const int mod = 1000000007;
      
    // To store the size of string and
    // number of queries
    static int n;
    //static int q;
      
    // To store parent and rank of ith place
    static int[]par = new int[N];
    static int[]Rank = new int[N];
      
    // To store maximum interval
    static Dictionary m = new Dictionary();
      
    // Function for initialization
    static void initialize()
    {
        for(int i = 0; i <= n; i++)
        {
            par[i] = i;
            Rank[i] = 0;
        }
    }
      
    // Function to find parent
    static int find(int x)
    {
        if (par[x] != x)
            par[x] = find(par[x]);
      
        return par[x];
    }
      
    // Function to make union
    static 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
    static long power(long a, long m1) 
    {
        if (m1 == 0)
            return 1;
        else if (m1 == 1)
            return a;
        else if (m1 == 2)
            return (1L * a * a) % mod;
        else if (m1 % 2 == 1)
            return (1L * a * power(
                   power(a, m1 / 2), 2)) % mod;
        else
            return power(power(a, m1 / 2), 2) % mod;
    }
      
    // Function to take maxmium interval
    static void query(int l, int r)
    {
        if (m.ContainsKey(l + r))
            m[l + r] = Math.Max(m[l + r], r);
        else
            m[l + r] = r;
    }
      
    // Function to find different possible strings
    static long possiblestrings() 
    {
        initialize();
      
        foreach(KeyValuePair i in m)
        {
            int x = i.Key - m[i.Key];
            int y = m[i.Key];
      
            // 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
    public static void Main(string[] args) 
    {
        n = 4;
      
        // Queries
        query(1, 3);
        query(2, 4);
      
        Console.Write(possiblestrings());
    }
    }
      
      
    // This code is contributed by rutvik_56


    输出:
    676