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

      

  • 相关阅读:
    SQL Server分页存储过程研究
    sql子查询 嵌套SELECT实用语句
    SQL语句优化
    CSS开发中常用技巧总结
    Html.DropDownList 的用法
    ADOStoredProc动态调用存储过程
    Sql Server 乐观锁和悲观锁理解和应用
    DOM 解析操作知识
    Java 中 Jar 命令的使用
    CDATA 基本知识
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10526831.html
Copyright © 2011-2022 走看看