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;
    }
    

      

  • 相关阅读:
    由VMnet引起的browser-sync故障解决方案
    Gen8折腾日记
    实变函数笔记(1)——集合与基数
    密码学笔记(6)——复杂度及其相关内容
    微分几何笔记(1)——参数曲线、内积、外积
    密码学笔记(5)——Rabin密码体制和语义安全性
    密码学笔记(4)——RSA的其他攻击
    密码学笔记(2)——RSA密码
    密码学笔记(1)——数论准备知识
    第七章小结
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10526831.html
Copyright © 2011-2022 走看看