前三题略

T4:

题目描述

小A有n个长度都是L的字符串。这些字符串只包含前8个小写字符,'a'~'h'。但这些字符串非常的混乱,它们几乎长得互不相同。小A想通过一些规则,让它们长得尽可能相同。小A现在有K次机会,他可以每次机会,可以选择一对字符x,y,让x,y变成等价的字符(注意这里x,y和字符'x', 'y'不是一样的,只是个代号)。注意,等价关系是有传递性的。比如小A让'a'和'b'等价, 'b'和'c'等价,那么'a'和'c'等价。
对于两个长度字符串P,Q是等价的,当且仅当对于每一位,P的字符和Q的字符都是等价的。
小A希望你告诉他,要怎么利用好这K次机会(当然可以不用完),使得尽可能多对字符串是等价的。注意每对字符串只能算一次。
数据包含10个数据点。每个数据点可能有不同的特性。
对于第1,2个数据点: 保证每个字符串只包含前4个小写字母
对于第3,4个数据点:每个字符串都只包含一种字母
对于第5,6个数据点:n<=10,L<=100
对于所有数据,满足:n <= 100, L <= 1000,K <= 28,每个字符串只包含前8个小写字母
 
题解:
普及组字符串???
肯定枚举了。
 
关键点,只有8个字符!!
K=28 有什么用?最多只要7个,就可以把所有都等价,就是n*(n-1)/2了。
 
所以,相当于是把a~h放进8-k个箱子里,每个箱子中的字符都是等价的。
 
第二类斯特林数,最多1701种情况。
 
枚举即可。
 
判断?
同一个箱子里的字符,干脆就是箱子编号算了。
 
直接比较肯定爆炸。
hash了。
但是,每次hsh一遍 ,1701*n*L只有60分
 

关键点还是只有8个字符!!

哈希本质还是一个P进制数

所以,对于每一个字符串的哈希,其实是每个字符作为这一位的数拼成的。

不一定每次必须要顺序从左到右,只要char * base^i做对,就可以嘛。

所以,可以记录下来,对于每一个字符串s,每一个字符c,c在s中出现的所有位置的base^i的和,可以预处理。

然后,每次判断的时候,

每个字符hsh就不用O(L)扫了。直接通过枚举每个字符的现在值,乘上预处理的base们和,再做和即可!

就O(8)处理一个串的哈希值了。

然后就 轻轻松松AC

代码:

注意箱子枚举的方法。

可以严格O(1701)处理,节省时间。

判断往之前箱子放,和新开箱子是有条件的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
const int M=;
const int mod=1e9+;
const ll P=; int n,l,k;
char a[N][M];
map<ll,int>mp;
ll mi[M];
ll sum[N][];
ll be[];
int sz[];
int ans=;
void dfs(int x,int box){
if(x==){
mp.clear();
int alike=;
bool fl=false;
for(int i=;i<=n;i++){
ll hsh=;
for(int j=;j<=;j++){
(hsh+=sum[i][j]*be[j])%=mod;
}
alike+=mp[hsh];
mp[hsh]+=;
} ans=max(ans,alike);
return;
}
if(-x>=k-box){
for(int i=;i<=box;i++){
be[x]=i;
sz[i]++;
dfs(x+,box);
be[x]=;
sz[i]--;
}
}
if(box<k&&sz[box]){
be[x]=box+;
sz[box+]++;
dfs(x+,box+);
be[x]=;
sz[box+]--;
}
}
int main()
{
scanf("%d%d%d",&n,&l,&k);
k=max(-k,);
for(int i=;i<=n;i++){
scanf("%s",a[i]+);
}
mi[]=;
for(int i=;i<=l;i++){
mi[i]=(mi[i-]*P)%mod;
}
for(int i=;i<=n;i++){
for(int j=;j<=l;j++){
(sum[i][a[i][j]-'a']+=mi[j])%=mod;
}
}
dfs(,);
printf("%d",ans);
return ;
}

总结:

这个题非常好的抓住了哈希的本质!

哈希是一个映射,但是本质是一个P进制数。

再利用8个字符的条件,就可以通过预处理,分着把hsh快速算出来了!

(以后如果碰到什么26个字符,但是长度很长,而且要重复hsh多次的,也许可以用上

而且是所有的一类字符变成另一类的那种。

 
 
 

牛客网NOIP赛前集训营-普及组(第一场)的更多相关文章

  1. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  2. [牛客网NOIP赛前集训营-普及组(第二场)]D-合法括号序列

    链接:https://www.nowcoder.com/acm/contest/165/D来源:牛客网 合法括号序列 键盘上有左括号(,右括号),和退格键-,共三个键. 牛牛希望按键n次,使得输入的字 ...

  3. 牛客网NOIP赛前集训营-普及组(第七场)

    链接:C 来源:牛客网 牛牛的同学给牛牛表演了一个读心术:牛牛先任意选定一个非负整数,然后进行N次操作:每次操作前,假设牛牛当前的数是a,那么这个操作可能是a = a + x, 或者a = a * x ...

  4. Nowcoder | [题解-N165]牛客网NOIP赛前集训营-普及组(第二场)

    啊...表示一大早还没睡醒就开始打比赛(开始前一分钟的我还在桌子上趴着休眠)...表示题目思路清奇(尤其C题)...但是我还是太蒻了...\(D\)题暴力都没打...题解正式开始之前先\(\%\)一下 ...

  5. 牛客网NOIP赛前集训营-普及组(第一场)C 括号

    括号 思路: dp 状态:dp[i][j]表示到i位置为止未匹配的 '(' 个数为j的方案数 状态转移: 如果s[i] == '(' dp[i][j] = dp[i-1][j] + dp[i-1][j ...

  6. 牛客网NOIP赛前集训营-普及组(第二场)

    T1 牛牛刚学习了输入输出,他遇到了一道这样的题目. 输入2个整数a和b 保证输入的a和b在long long范围之内,即满足 -9223372036854775808 <= a, b < ...

  7. 牛客网NOIP赛前集训营-普及组

    第一场: A-绩点 题目描述 小A刚考完大学考试.现在已经出了n门课的成绩,他想自己先算一下这些课的绩点是多少.设第i门课的他拿到的绩点是gpai,而这门课的学分是sci,那么他的总绩点用下面的公式计 ...

  8. 牛客网 NOIP赛前集训营-普及组(第四场)C--部分和 (高维前缀和)

    传送门 解题思路 高维前缀和模板题.首先,求前缀和有两种方式,比如说对于求二维前缀和来说. 第一种 : for(int i=1;i<=n;i++) for(int j=1;j<=n;j++ ...

  9. 牛客网NOIP赛前集训营-提高组(第四场)游记

    牛客网NOIP赛前集训营-提高组(第四场)游记 动态点分治 题目大意: \(T(t\le10000)\)组询问,求\([l,r]\)中\(k(l,r,k<2^{63})\)的非负整数次幂的数的个 ...

随机推荐

  1. 05-matplotlib-直方图

    import numpy as np import matplotlib.pyplot as plt ''' 由于一系列不等的纵形图组成,表示数据分布的情况 例如:某年级同学的身高分布 需要注意与 柱 ...

  2. traceroute命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/peida/archive/2013/03/07/2947326.html 通过traceroute我们可以知道信息从你 ...

  3. nodejs 服务器实现区分多客户端请求服务

    初始实现 var net = require('net');//1 引入net模块 var chatServer = net.createServer();//创建net服务器 var clientL ...

  4. C++:模板——函数模板1

    一.为什么使用函数模板 假设我们在程序中需要比较两个变量的大小,但变量的类型可能是int.float或者double,此时为了满足程序的要求我们可能会在程序中编写多个函数,如: //比较两个int型变 ...

  5. iOS开发学习-给圆形图片添加边框

    imageView.layer.cornerRadius = imageView.bounds.size.width * 0.5;// 设置圆角刚好是自身宽度的一半,就刚好是圆形 imageView. ...

  6. github基础操作

    1.最简单实用的操作 更新远程仓库 git status git add . git commit -m "add" git push #git push -u origin ma ...

  7. ubuntu下安装matlab2015b

    ========= 安装过程 1.下载MATLAB2015b破解版 操作系统:Ubuntu 16.04 LTS 程序文件:Matlab2015b-glnxa64破解版 解压提取文件:在ubuntu系统 ...

  8. p4factory下 targets/basic_rout

    p4factory/targets/basic_routing/p4src代码解读 headers.p4 header_type ethernet_t { fields { dstAddr : 48; ...

  9. Ubuntu16.04 下虚拟环境的创建与使用

    1. 虚拟环境   虚拟环境(virtual environment),顾名思义是虚拟出来的环境,通俗来讲,可以借助虚拟机,docker来理解虚拟环境,就是把一部分内容独立出来,我们把这部分独立出来的 ...

  10. testNg-build.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?> <proje ...