zoukankan      html  css  js  c++  java
  • RMQ 字符串 F. Strings and Queries

    F. Strings and Queries
    time limit per test
    2.5 s
    memory limit per test
    256 MB
    input
    standard input
    output
    standard output

    You are given a set of n strings such that all characters in the strings are 'a', 'b', or 'c'.

    Also, you are given q queries, such that each query consisting of two strings a and b. The answer of each query is the index of the string with the most number of palindrome substrings between strings a and b from the given set.

    A substring of the string s is a sequence sl, sl + 1, ..., sr for some integers (l, r) such that (1 ≤ l ≤ r ≤ n), where n is the length of the string s.

    A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as "madam" or "racecar".

    Input

    The first line contains an integer T, where T is the number of test cases.

    The first line of each test case contains two integers n and q (1 ≤ n ≤ 104) (1 ≤ q ≤ 105), where n is the number of strings, and q is the number of queries.

    Then n lines follow, each line contains a non-empty string with length no more than 30, giving the strings. All characters in the strings are 'a', 'b', or 'c'. It is guaranteed that all strings are unique. The given strings are numbered from 1 to n.

    Then q lines follow, each line contains two strings a and b, giving the queries. It is guaranteed that strings a and b exist in the given set of strings.

    Output

    For each query, print a single line containing the index of the string with the most number of palindrome substrings between the given strings a and b. If there are more than one answer, print the lowest index.

    Example
    Input
    Copy
    1
    5 5
    aaaaa
    abaabc
    cbbaca
    abccba
    abca
    aaaaa abca
    cbbaca abccba
    abaabc abccba
    abccba abca
    abaabc abccba
    Output
    Copy
    1
    4
    2
    4
    2
    Note

    As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

    这个是是一个RMQ的题目,

    我分析一下我的思路,首先从学姐那里知道这个是一个RMQ的题目,然后就打开了这个模板(不太记得怎么写了),然后开始思考,这个是字符串,首先要把字符变成数字来处理,这个就需要一个数组或者map来储存它的位置,然后还要用一个map来储存每一个位置的子字符串数量,最后就是dp来储存编号,然后方便以后的储存。

    之后的m次查询,每次找到它的位置在那里,然后用RMQ进行查询。

    RMQ具体就是比较dp编号位置的字符回文子串的数量。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <string>
    #include <math.h>
    #include <algorithm>
    #include <map>
    #define inf 0x3f3f3f3f
    #define debug(n) printf("%d
    ",n)
    using namespace std;
    typedef long long ll;
    const int maxn = 1e4 + 100;
    ll dp[maxn][30];
    map < ll, ll > mp;
    map<ll, ll>mm;
    ll n, m;
    
    ll tras(char* s)
    {
    	ll ans = 0;
    	for (int i = 0; i <s[i]; i++)//这里还是不太明白为什么这么写,有哪位大佬知道,可以告诉我一声。
    	{
    		ans = ans * 27 + s[i] - 'a' + 1;
    	}
    	return ans;
    }
    
    ll getnum(char*s)
    {
    	int len = strlen(s);
    	ll ans = 0;
    	for (int i = 0; i < len; i++)
    	{
    		for (int j = 0; i + j < len && i - j >= 0 && s[i - j] == s[i + j]; j++) ans++;
    		for (int j = 0; i + j < len && i - 1 - j >= 0 && s[i - 1 - j] == s[i + j]; j++) ans++;
    	}
    	return ans;
    }
    int max_(ll a, ll b)
    {
    	if (mm[a] == mm[b]) return a < b ? a : b;
    	return mm[a] > mm[b] ? a : b;
    }
    
    void RMQ()
    {
    	for (int j = 1; (1 << j) <= n; j++)
    	{
    		for (int i = 1; i + (1 << j) - 1 <= n; i++)
    		{
    			dp[i][j] = max_(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
    		}
    	}
    }
    
    int main()
    {
    	int t;
    	cin >> t;
    	while (t--)
    	{
    		cin >> n >> m;
    		char s[100], s1[100];
    		mm.clear();
    		mp.clear();
    		memset(dp, 0, sizeof(dp));
    		for (int i = 1; i <= n; i++)
    		{
    			scanf("%s", s);
    			mp[tras(s)] = i;
    			mm[i] = getnum(s);
    			dp[i][0] = i;
    		}
    		RMQ();
    		for (int i = 1; i <= m; i++)
    		{
    			scanf("%s%s", s, s1);
    			ll l = mp[tras(s)];
    			ll r = mp[tras(s1)];
    			if (l > r) swap(l, r);
    			ll k = (log(r - l + 1.0) / (log(2.0)));
    			ll num = max_(dp[l][k], dp[r - (1 << k) + 1][k]);
    			printf("%lld
    ", num);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    树莓派服务器搭建
    设计模式之装饰者模式
    设计模式之建造者模式
    Java IO
    设计模式之抽象工厂模式
    常用排序算法(堆排序)
    Struts2框架简介和示例
    静态代理和利用反射形成的动态代理(JDK动态代理)
    常用排序算法(插入排序,快速排序,归并排序,堆排序)
    设计模式之简单工厂和工厂方法模式
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10526831.html
Copyright © 2011-2022 走看看