【题解】2022ICPC杭州-K

翻译

原题链接
在这里插入图片描述
  简述一下就是每次询问重新定义一个字母排序表,问在这个顺序下n个字符串的序列的逆序数是多少。

字典树计算逆序数

  先考虑初始状况下,即 a < b < . . . < z a<b<...<z a<b<...<z的情况下,逆序数如何计算。而对于这种多字符串问题,优先考虑的肯定是字典树,我们可以对所有字符串构建一棵字典树,在字典树的每个节点上记录所有经过它的字符串的下标,然后计算两种情况的逆序数:

  (1) S i S_{i} Si S j S_{j} Sj的前缀,则它们在字典树上的情况一定会在某一个节点 n o d e t node_{t} nodet处满足 i ∈ n o d e t , j ∈ n o d e t i \in node_{t}, j \in node_{t} inodet,jnodet,而 i i i将不会出现在 n o d e t node_{t} nodet的任何子节点上,假如 i > j i > j i>j,那就产生了一组逆序对。我们记这种情况的总逆序数为 A N S 1 ANS_{1} ANS1

  (2) S i S_{i} Si S j S_{j} Sj存在一位不一样的字符,则一定存在一个节点 n o d e t node_{t} nodet,在这里两个字符串走了不同的路,称这两个字符串在这个节点上出现了分歧(后面要用)。于是我们可以遍历每个节点下的两条分支,在这两个分支中跑一遍求逆序数,采用双指针的方式,类似归并排序时求逆序数,复杂度大约为 O ( 13 ∗ 26 ∗ n ) O(13*26*n) O(1326n),记这种情况的总逆序对数为 A N S 2 ANS_{2} ANS2

  于是,答案就是 A N S 1 + A N S 2 ANS_{1}+ANS_{2} ANS1+ANS2

打乱字母表下如何计算逆序数

  那么好,现在考虑字母表排序打乱的情况,上述过程会有什么变化。容易发现,第一种情况不会受到任何影响,仍然是 A N S 1 ANS_{1} ANS1

  对于第二种情况,假如新的顺序变成了 a > b a>b a>b,发现原本因为分歧原因为 a a a b b b的字符串大小关系发生变化,在初始的排序下,我们不再需要它们的逆序对,而是要顺序对。而这种变化会在 a a a b b b大小关系变化时同时发生,可以将所有因此需要调整的地方统一处理。

  思路可能有点抽象,直接上方法。不再直接求 A N S 2 ANS_{2} ANS2,而是两个列表 w 1 [ 26 ] [ 26 ] w_{1}[26][26] w1[26][26] w 2 [ 26 ] [ 26 ] w_{2}[26][26] w2[26][26],其中 w 1 [ c 1 ] [ c 2 ] w1[c_{1}][c_{2}] w1[c1][c2]表示两个字符串因为 c 1 c_{1} c1 c 2 c_{2} c2产生了分歧而产生的顺序对数, w 2 w_{2} w2则是逆序对数,则初始的 A N S 2 ANS2 ANS2其实可以直接表示为:

A N S 2 = ∑ i = 0 25 ∑ j = i + 1 25 w 2 [ i ] [ j ] ANS_{2}=\sum_{i=0}^{25}\sum_{j=i+1}^{25}w_{2}[i][j] ANS2=i=025j=i+125w2[i][j]

  而在新的顺序下,我们设一个数组 w e i g h t [ 26 ] weight[26] weight[26]表示 a a a z z z的权重,则 A N S 2 ANS_{2} ANS2可以表示为:

A N S 2 = ∑ i = 0 25 ∑ j = i + 1 25 w 1 [ i ] [ j ] ∗ ( i f w e i g h t [ i ] > w e i g h t [ j ] ) ANS_{2}=\sum_{i=0}^{25}\sum_{j=i+1}^{25}w_{1}[i][j]*(if\ weight[i]>weight[j]) ANS2=i=025j=i+125w1[i][j](if weight[i]>weight[j])
+ ∑ i = 0 25 ∑ j = i + 1 25 w 2 [ i ] [ j ] ∗ ( i f w e i g h t [ i ] < w e i g h t [ j ] ) \ \ \ \ \ \ \ \ \ \ \ \ +\sum_{i=0}^{25}\sum_{j=i+1}^{25}w_{2}[i][j]*(if\ weight[i]<weight[j])             +i=025j=i+125w2[i][j](if weight[i]<weight[j])

  最后别忘了加上 A N S 1 ANS_{1} ANS1

时间复杂度

  建树阶段为 O ( ∑ i = 1 n ∣ S i ∣ ) O(\sum_{i=1}^{n}|S_{i}|) O(i=1nSi)
  求 A N S 1 ANS_{1} ANS1阶段为 O ( ∑ i = 1 n ∣ S i ∣ ) O(\sum_{i=1}^{n}|S_{i}|) O(i=1nSi)
  求 w 1 w_{1} w1 w 2 w_{2} w2阶段为 O ( 13 ∗ 26 ∗ ∑ i = 1 n ∣ S i ∣ ) O(13*26*\sum_{i=1}^{n}|S_{i}|) O(1326i=1nSi)
  回答询问阶段为 O ( 13 ∗ 26 ∗ q ) O(13*26*q) O(1326q)

  注意,上述时间复杂度只是大约,大概率达不到,且中间有一些微微的剪枝优化

  此外,千万不要新建一个vector并用另一个vector给它赋值,只为了弄个新的变量名方便写代码,因为vector赋值是默认 O ( s i z e ) O(size) O(size)一个一个拷贝过去的,而不是指针!!!(因为这个TLE了半天)

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node{int nxt[26];int value=-1;int h;vector<int> v;
} G[1000006];
int H[500005];
int new_weight[26];
int szG=1;
int w;     // 子串形成的逆序对数
int w1[26][26], w2[26][26];   // i与j的比较中产生的逆序对数, 反转后产生的逆序对数
int n, q;
inline void ct(int x, int y) {    // 求w1顺序对, w2逆序对if(G[x].value > G[y].value) swap(x, y);    // 保证分别为a子树,b子树int value1 = G[x].value, value2 = G[y].value;int t1 = 0, t2 = 0;while(t1 < G[x].v.size() && t2 < G[y].v.size()) {if(G[x].v[t1] < G[y].v[t2]) {w2[value1][value2] += G[y].v.size() - t2;t1 ++;} else {w1[value1][value2] += G[x].v.size() - t1;t2 ++;}}
}
inline void ct2(int x) {    // 求ANS1,即前缀关系的逆序数vector<int> v1, v2;     // 消失的,剩余的for(int i=0;i<G[x].v.size();i++) {int now = G[x].v[i];if(H[now] == G[x].h) {v1.push_back(now);} else {v2.push_back(now);}}int t1 = 0, t2 = 0;while(t1 < v1.size() && t2 < v2.size()) {if(v1[t1] < v2[t2]) {t1 ++;} else {w += v1.size() - t1;t2 ++;}}
}
inline void dfs(int id) { if(id != 0 && G[id].v.size() <= 1) return;for(int i=0;i<26;i++) {if(G[id].nxt[i] == 0) continue;for(int j=i+1;j<26;j++) {if(G[id].nxt[j] == 0) continue;ct(G[id].nxt[i], G[id].nxt[j]);}}ct2(id);for(int i=0;i<26;i++) {if(G[id].nxt[i] == 0) continue;dfs(G[id].nxt[i]);}
}
signed main() {cin>>n>>q;for(int i=1;i<=n;i++) {string s; cin>>s;H[i] = s.length();int id = 0;   // 根for(int j=0;j<s.size();j++) {if(G[id].nxt[s[j]-'a'] == 0) {   // 下一个节点不存在G[szG].value = s[j] - 'a';G[szG].h = G[id].h + 1;G[id].nxt[s[j]-'a'] = szG;szG++;}id = G[id].nxt[s[j]-'a'];G[id].v.push_back(i);}}dfs(0);while(q--) {           string s; cin>>s;for(int i=0;i<26;i++) {new_weight[s[i]-'a'] = i;}int sum = 0;for(int i=0;i<26;i++) {for(int j=i+1;j<26;j++) {if(new_weight[i] < new_weight[j])sum += w1[i][j];elsesum += w2[i][j];}}printf("%lld\n", w + sum);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/434567.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SAP ABAP] 锁对象

在SAP中使用锁对象&#xff0c;用于避免在数据库中插入或更改数据时出现不一致的情况 1.创建锁对象 数据准备 学校表(ZDBT_SCH_437) 使用事务码SE11创建锁对象 点击"锁对象"单选按钮&#xff0c;输入以E开头的锁定对象的名称&#xff0c;然后点击创建按钮 锁对象名…

看480p、720p、1080p、2k、4k、视频一般需要多大带宽呢?

看视频都喜欢看高清&#xff0c;那么一般来说看电影不卡顿需要多大带宽呢&#xff1f; 以4K为例&#xff0c;这里引用一位网友的回答&#xff1a;“视频分辨率4092*2160&#xff0c;每个像素用红蓝绿三个256色(8bit)的数据表示&#xff0c;视频帧数为60fps&#xff0c;那么一秒…

基于VUE的在线茶叶购物网站的设计与实现后端SpringBoot数据库MySQL

目录 1. 项目结构规划 2. 技术选型与工具链 3. 关键功能模块设计 4. 数据库设计 5. 安全性考虑 6. 性能优化建议 在开发一个在线茶叶购物网站之前&#xff0c;了解相关的研究背景和技术发展趋势是非常重要的。以下是一些关键点&#xff0c;可以帮助理解该项目的开发背景和…

召回07 双塔模型——正负样本

正样本&#xff1a; 二八法则&#xff0c;少部分物品占据了大多数点击&#xff0c;会导致正样本大多是热门物品。以一定的概率抛弃一些热门物品&#xff0c;抛弃的概率与样本的点击次数正相关。 负样本&#xff1a; 简单负样本 上述简单负样本是从全体样本中抽样。其中&#…

Python编码系列—Python备忘录模式:掌握对象状态保存与恢复技术

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

[Redis][Zset]详细讲解

目录 0.前言1.常见命令1.ZADD2.ZCARD3.ZCOUNT4.ZRANGE5.ZREVRANGE6.ZRANGEBYSCORE7.ZPOPMAX8.BZPOPMAX9.ZPOPMIN10.BZPOPMIN11.ZRANK12.ZREVRANK13.ZSCORE14.ZREM15.ZREMRANGEBYRANK16.ZREMRANGEBYSCORE17.ZINCRBY 2.集合间操作1.有序集合的交集操作2.ZINTERSTORE3.有序集合的并…

H5响应式的文化传媒娱乐公司HTML网站模板源码

源码名称&#xff1a;响应式的文化传媒娱乐公司HTML网站模板源码 源码介绍&#xff1a;一款自适应H5文化传媒娱乐公司官网源码&#xff0c;源码带有6个H5页面&#xff0c;可用于文化传媒和娱乐公司官网。 需求环境&#xff1a;H5 下载地址&#xff1a; https://www.51888w.c…

Netty系列-5 Netty启动流程

背景 Netty程序有固定的模板格式&#xff0c;以ServerBootstrap为例: public class NettyServer {public void start(int port) {ServerBootstrap serverBootstrap new ServerBootstrap();EventLoopGroup boosGroup new NioEventLoopGroup(1);EventLoopGroup workGroup ne…

Kubernetes配置管理(kubernetes)

实验环境&#xff1a; 在所有节点上拉取镜像&#xff1b;然后把资源清单拉取到第一个master节点上&#xff1b; 同步会话&#xff0c;导入镜像&#xff1a; configmap/secret 配置文件的映射 变量&#xff1a; 基于valuefrom的方式 cm--》pod 特点&#xff1a;变量的名称可…

[JavaEE] IP协议

目录 一、 IP协议 1.1 基本概念 1.2 协议头格式 1.3 特殊IP 二、 地址管理 2.1 网段划分 2.2 CIDR(Classless Interdomain Routing) 2.3 私有IP地址和公网IP地址 2.4 NAT(Network Address Translation)-网络地址转换 2.5 路由选择 三、数据链路层 3.1 认识以太网 3…

什么是AQS

目录 AQS 介绍 原理 以可重入的互斥锁 ReentrantLock 为例 以倒计时器 CountDownLatch 以例 AQS 资源共享方式 实现自定义同步器 示例 性能优化 AQS 介绍 AQS &#xff08;AbstractQueuedSynchronizer &#xff09;&#xff0c;抽象队列同步器。AQS 是一个功能强大且…

cmd命令大全详解

CMD是Windows操作系统中的命令行解释器&#xff0c;它允许用户通过键入命令来执行各种操作。以下是一些常用的CMD命令及其简要说明&#xff1a; dir - 显示目录中的文件和子目录。 cmddir cd - 更改当前目录。 cmdcd [目录路径] mkdir - 创建新目录。 cmdmkdir [目录名] rmd…

Vue.js 与 Flask/Django 后端配合开发实战

Vue.js 与 Flask/Django 后端配合开发实战 在现代的 Web 开发中&#xff0c;前后端分离已成为一种主流架构&#xff0c;其中前端使用 Vue.js 等流行的框架&#xff0c;后端采用 Flask 或 Django 提供 API 接口。在这种开发模式下&#xff0c;前端负责页面的交互和动态效果&…

将Mixamo的模型和动画导入UE5

首先进入Mixamo的官网 , 点击 Character 选择一个模型 (当然你也可以自己上传模型/绑定动画) 然后点击下载 , 这个作为带骨骼的模型 选择FBX格式 , T Pose 直接下载 点击 Animations 选择动画 , 搜索 idle 默认站立动画 点击下载 , 格式选择 FBX , 不带模型只要骨骼 , 帧数选6…

前端面试经验总结2(经典问题篇)

谈谈你对前端的理解 前端主要负责产品页面部分的实现&#xff0c;是最贴近于用户的程序员。 基本工作要求&#xff1a; 1.参与项目&#xff0c;通过与团队成员&#xff0c;UI设计&#xff0c;产品经理的沟通&#xff0c;快速高质量的实现效果图&#xff0c;并能够精确到1px 2.做…

大模型培训讲师叶梓:Llama Factory 微调模型实战分享提纲

LLaMA-Factory ——一个高效、易用的大模型训练与微调平台。它支持多种预训练模型&#xff0c;并且提供了丰富的训练算法&#xff0c;包括增量预训练、多模态指令监督微调、奖励模型训练等。 LLaMA-Factory的优势在于其简单易用的界面和强大的功能。用户可以在不编写任何代码的…

TypeScript介绍和安装

TypeScript介绍 TypeScript是由微软开发的一种编程语言&#xff0c;它在JavaScript的基础上增加了静态类型检查。静态类型允许开发者在编写代码时指定变量和函数的类型&#xff0c;这样可以在编译时捕获潜在的错误&#xff0c;而不是等到运行时才发现问题。比如&#xff0c;你…

论文笔记:iCaRL: Incremental Classifier and Representation Learning

1. Contribution 提出了一种新的训练策略&#xff0c;iCaRL&#xff1a;允许以增量方式学习&#xff1a;只需要同时存在一小部分类别的训练数据&#xff0c;新类别可以逐步添加。同时学习分类器和数据表示&#xff1a;iCaRL能够同时学习强大的分类器和数据表示&#xff0c;这与…

[SAP ABAP] SELECTION-SCREEN

SELECTION-SCREEN用来调节系统生成的画面 REPORT z437_test_2024.TABLES: mara, zdbt_sch_437.SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001. " Title1 PARAMETERS:p_1 DEFAULT A,p_2 TYPE char10. SELECTION-SCREEN END OF BLOCK b1.SELECTION-SCREEN …

实现微信小程序中点击单词显示在input的交互功能指南

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…