当前位置: 首页 > article >正文

Educational Codeforces Round 159(div2) --- E. Collapsing Strings-- 题解

目录

E. Collapsing Strings

题目大意:

思路:

代码:


E. Collapsing Strings

Problem - E - Codeforces

题目大意:

给你n个字符串,然后对任意两个字符串进行合并操作,

设两个字符串 a 和 b 的折叠 C(a,b) 是以下操作:

  • 如果 a 为空,则 C(a,b)=b;
  • 如果 b 为空,则 C(a,b)=a;
  • 如果 a 的最后一个字母等于 b 的第一个字母,则 C(a,b)=C(a1,|a|−1,b2,|b|) ,其中 sl,r是 s 的子字符串,从  第l 个字母到 第r 个字母;
  • 否则为 C(a,b)=a+b ,即两个字符串的串联。

然后计算任意两个字符串合并后的长度和。

n <= 10^6, |s| <= 10^6 并且总的字符串长度为10^6

思路:

即如果两个字符串的前缀和后缀相同,应该将这部分相同的前缀和后缀去掉(就是消消乐),然后他们剩下的字符串长度就是答案。

如果暴力求的话复杂度是len * n * n为10^18的次方,这是不能接受的,所以需要进行预处理,将部分相同的前缀和后缀全部去掉这一件事其实可以看作是寻找前缀匹配长度,如果有匹配需要删除此部分贡献的答案。

所以可以构建一个前缀树,然后在匹配时,将每一个字符串倒序,后缀就变成了前缀,便可以利用这个已经构造后的前缀树快速得到答案。

for (int i = 1; i <= n; i++) {
            str[i] = input.next();
            build(str[i]); // 构建前缀树
            sum += str[i].length();
        }
        sum *= 2L * n; // 如果没有任意一对字符串可以匹配时的答案。
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= str[i].length(); j++) ans[j] = 0;
            query(str[i]); // 
            for (int j = str[i].length() - 1; j >= 0; j--) {
            // 将拥有相同前缀和后缀的答案进行删除
                sum -= 2L * (j + 1) * (ans[j] - ans[j + 1]); 
            }
        }
public static void build(String str){
        char[] s = str.toCharArray();
        int p = 0;
        for (int i = 0; i < s.length; i++) {
            int j = s[i] - 'a';
            if (tree[p][j] == 0) tree[p][j] = ++idx;
            p = tree[p][j];
            cnt[p]++;
        }
    }

    public static void query(String str){
        char[] s = str.toCharArray();
        int p = 0;
        for (int i = 0; i < s.length; i++) {
            int k = str.length() - i - 1; // 使用对应编号,这里相当于是对逆序的优化
            int j = s[k] - 'a';
            if (tree[p][j] == 0) return; // 如果当前位置没有匹配的前缀,退出
            p = tree[p][j]; 
            ans[i] = cnt[p]; // 拥有匹配相同前缀的字符串个数
        }
    }

代码:

import java.util.Scanner;

/**
 * @ProjectName: study3
 * @FileName: Ex41
 * @author:HWJ
 * @Data: 2023/12/4 19:48
 */
public class Ex41 {
    static int N = (int) (1e6 + 6);
    static int[] cnt = new int[N];
    static int[][] tree = new int[N][30];
    static long[] ans = new long[N];
    static String[] str = new String[N];
    static int idx = 0;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        long sum = 0;
        for (int i = 1; i <= n; i++) {
            str[i] = input.next();
            build(str[i]);
            sum += str[i].length();
        }
        sum *= 2L * n;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= str[i].length(); j++) ans[j] = 0;
            query(str[i]);
            for (int j = str[i].length() - 1; j >= 0; j--) {
                sum -= 2L * (j + 1) * (ans[j] - ans[j + 1]);
            }
        }
        System.out.println(sum);
    }
    public static void build(String str){
        char[] s = str.toCharArray();
        int p = 0;
        for (int i = 0; i < s.length; i++) {
            int j = s[i] - 'a';
            if (tree[p][j] == 0) tree[p][j] = ++idx;
            p = tree[p][j];
            cnt[p]++;
        }
    }

    public static void query(String str){
        char[] s = str.toCharArray();
        int p = 0;
        for (int i = 0; i < s.length; i++) {
            int k = str.length() - i - 1;
            int j = s[k] - 'a';
            if (tree[p][j] == 0) return;
            p = tree[p][j];
            ans[i] = cnt[p];
        }
    }
}


http://www.kler.cn/news/156969.html

相关文章:

  • Redis数据库
  • 卷麻了,00后测试用例写的比我还好,简直无地自容......
  • spring日志输出到elasticsearch
  • 【有机化学(药学类)】醛和酮3
  • 刷题系列——排序算法
  • Python面向对象③:封装【侯小啾Python基础领航计划 系列(二十一)】
  • 5.【自动驾驶与机器人中的SLAM技术】2D点云的scan matching算法 和 检测退化场景的思路
  • Android之 知识总结第二篇
  • 用python写一个简单的爬虫
  • 三次握手四次挥手
  • Google Protocol Buffers (proto3) 中的 DoubleValue 类型用法总结
  • linux创建新的py文件
  • 电商项目之Web实时消息推送(附源码)
  • 入门Python+Vue 全栈开发高级BI数据的可视化实战项目几个技术点总结
  • 2023年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——解析版
  • 131. 分割回文串
  • JMeter从入门到精通
  • 个人Windows电脑通过Cloudreve+Cpolar搭建PHP云盘系统公网可访问
  • 机器学习(1)机器学习类型和机器学习的主要概念
  • 练习十一:简单卷积器的设计
  • 纯C读取文件实现解析H264裸流每一帧数据
  • 回归分析:预测和建模
  • Git 简介及异常场景处理
  • 12月4日作业
  • 作业12.4
  • 分享77个菜单导航JS特效,总有一款适合您
  • JDBC常见的几种连接池使用(C3P0、Druid、HikariCP 、DBCP)(附上代码详细讲解)
  • 软件测试【理论基础】
  • 基于AT89C51单片机的秒表设计
  • Python机器学习、深度学习入门丨气象常用科学计算库、气象海洋常用可视化库、爬虫和气象海洋数据、气象海洋常用插值方法、EOF统计分析、WRF模式后处理等