文章

18

粉丝

183

获赞

57

访问

101.8k

头像
1738 前缀合+差分复习
P1738 华东师范大学2020年机试题
发布于2022年9月3日 15:38
阅读数 5.5k

看到这种题目

“给定q个查询...”能够很明显的定位到用前缀合解决。因为虽然算法本身时间复杂度还过得去,但是每次查询都要经过一次计算,查询次数一多,非常容易超时。所以一定是先算再存再查,提高效率。

 

解题思路

  • 判断两个子串中每个字母的出现次数是否相同,即要计算子串中每个字母出现的次数
  • 我们可以计算出遍历到第i个字符时,每个字母在前i个字符中出现的次数,用a[i][j]表示。i表示当前的位置,j表示字母
  • 字母j在l和r区间出现的次数就等于a[r][j]-a[l-1][j]。(为什么是l-1,自己写一个字符串一算就知道了。属于一个半开闭区间)
  • 计算出所有的a[i][j],再查询即可

 

这里给出一份学习前缀合和查分非常好的博客:差分和前缀合

另外,在多次tle后发现,使用cin和cout超时,所以使用scanf和printf。


代码如下:

#include <bits/stdc++.h>
using namespace std;

int a[50001][27]; //a[i][j]表示在第i个位置时,字母j一共出现的次数

void pre(string s)
{
    memset(a, 0, sizeof(a));

    int len = s.size();

    for (int i = 1; i <= len; i++)
    {
        for (int j = 0; j < 26; j++)
        {
            int c_num = s[i] - 'a'; //字符转化为数字
            int add = 0;            //增量
            if (j == c_num)
                add = 1;
            a[i][j] = a[i - 1][j] + add;
        }
    }
}

bool jud(int xs, int xe, int ys, int ye)
{
    for (int j = 0...
登录查看完整内容


登录后发布评论

暂无评论,来抢沙发