Week3_250303~250309_OI日志
250303
大致安排
上午讲了字符串hash初步,感觉很NB,下午补题,但因为字符串太菜,补题速度过于缓慢。
题目
- P3370 【模板】字符串哈希
- U461211 字符串 Hash(数据加强)
- P3763 [TJOI2017] DNA
字符串 k k k 次失配问题,在这里 k = 3 k=3 k=3 ,直接枚举起始位置,并三次二分失配位置即可,字符串hash判断即可。但需要注意一点hash复杂度可能凭空多log,时间复杂度从而达到惊人的 O ( T ⋅ n ⋅ 3 ⋅ l o g 2 ( n ) ⋅ l o g ? ( ? ) ) O(T \cdot n \cdot 3 \cdot log_2(n) \cdot log_?(?)) O(T⋅n⋅3⋅log2(n)⋅log?(?)),常数飞起。这时考虑到有前几位均不失配的概率很小,且数据比较随机,所以直接手动特判,而不上二分。或者是,改成单模数,不过我一般设 998244 8 53 998244\color{red}8\color{black}53 998244853。 - P4824 [USACO15FEB] Censoring S
考虑这个操作,就是个栈,而且每次删的字符串长度固定,考虑如何判断何时删,在栈上维护一个动态的字符串hash - P4407 [JSOI2009] 电子字典
这道题有 2 2 2 种解法:
方法一,把操作一次后的字符串搞出来放入先前建好的Trie树上跑查询。
方法二,hash扔进map 特别注意这里的操作二"+" 必须将原字典字符串操作扔到一个新的map进行查询,否则凭空 26 26 26 倍常数,导致TLE - AT_arc172_c [ARC172C] Election
数学,hash均可解决
字符串hash
字符串哈希无非就是将一个繁琐的东西给加密,使其冲突概率尽可能小,在一定判断情况下,时间复杂度从
O
(
n
)
O(n)
O(n) =>
O
(
1
)
O(1)
O(1)
自然溢出哈希极可能被卡,单模数极容易出冲突,双模数比较稳定,但现在CF上有专门根据base和mod卡多模数哈希的字符串,但其生成的长度和时间好像是关于一个常数的多模数的指数级别。(应该没人卡)
下面是老师提供的一个多模数的哈希代码:
加密方式
h
s
h
i
=
h
s
h
i
−
1
⋅
b
a
s
e
+
s
i
hsh_i=hsh_{i-1}\cdot base+s_i
hshi=hshi−1⋅base+si
struct Hash2{
int le;
string s;
vector<int>hsh[2],pmod[2]; //这里可以根据需求更改模数数量
//初始化
Hash2(string& _s){
s=_s;
le=s.size();
for(int j=0;j<2;j++){
hsh[j].resize(le+1);
pmod[j].resize(le+1);
hsh[j][0]=0;pmod[j][0]=1;
}
for(int j=0;j<2;j++){
for(int i=1;i<=le;i++){
pmod[j][i]=pmod[j][i-1]*base[j]%mod[j];
hsh[j][i]=(hsh[j][i-1]*base[j]+s[i-1])%mod[j];
}
}
}
//区间访问
pair<int,int> get(int l,int r){
vector<int>ret(2);
for(int j=0;j<2;j++){
ret[j]=hsh[j][r]-hsh[j][l-1]*pmod[j][r-l+1];
ret[j]=(ret[j]%mod[j]+mod[j])%mod[j];
}
return make_pair(ret[0],ret[1]);
}
};
250304
大致安排
上午老师讲了讲线段树上维护哈希,非常好理解,下午比赛AT_abc325,结果全机房被D卡了,我决定死磕D,结果没搞定死了,掉大分。
题目
- P3449 [POI 2006] PAL-Palindromes
这道题也可以不保证给定串是回文串去做。
回文串翻转与原串相同,如果 i − j i-j i−j 是回文,则 反 j − 反 i 反j-反i 反j−反i 应和它相同,但因为题目保证 i 、 j i、j i、j 均为回文串,所以 j − i j-i j−i 相同即可,我们写出来他们的哈希式子变换一下:
map维护一下这个东西就可以了 - AT_abc325_a
- AT_abc325_b
- AT_abc325_c
- AT_abc325_d
(不应该把它给拆开成两个时间,要不然很多需要注意的地方,其计算价值方式不同) - AT_abc325_e
分层图板子 - AT_abc325_f
观察到覆盖的区间和 2 2 2 种传感器的数量都非常少,如果每种传感器用的数量知道了自然便知道了花费,因此把其中一个传感器打入dp存的最值。
设 f i , j f_{i,j} fi,j 表示前 i i i 个区间,花费了 j j j 个第一种传感器,最小需要多少个第二种传感器。
时间复杂度: O ( n ⋅ k 0 ⋅ k 1 ) O(n\cdot k_0\cdot k_1) O(n⋅k0⋅k1) - CF1200E Compress Words
类 P4824维护栈里字符串哈希 - CF452F Permutation
若出现一个长度为 3 3 3 的等差数列,我们设中间的元素为 m i d mid mid,则两边的元素分别为 m i d − k , m i d + k mid-k,mid+k mid−k,mid+k
可以发现这两个数关于 m i d mid mid 对称,这有什么用,那么我们可以在桶上观察一下,如果现在搞到一个数 m i d mid mid 如果没有以它为中心的长度为 3 3 3 的等差数列,则 ∀ m i d − k , m i d + k \forall mid-k,mid+k ∀mid−k,mid+k 均在同侧,这时一侧的桶将成为一个以 m i d mid mid 为中心的前缀或后缀回文串,回文串我们可以在线段树上维护两个方向的哈希,这道题便完美解决了。
250305
大致安排
上午把昨天的AT_abc325的题(以后尽量先保底为好),又把基于梅森旋转算法的和哈希、异或哈希给讲了。
题目
- gym102798G Caesar Cipher
题意大致为:区间在 m o d 65536 \mod 65536 mod65536 意义下 + 1 +1 +1 ;区间查询两段区间(认定为字符串)是否相同。
这道题如果抛开 + 1 m o d 65536 +1 \mod 65536 +1mod65536 这将是区间加一个关于base的等比数列。
方法1:差分,取模就没用了,直接搞定。
方法2:观察到区间只会 + 1 +1 +1 操作数量 5 e 5 5e5 5e5 级别,一个数肯定最多加到 65536 65536 65536 次数达不到 10 10 10 如果我们暴力单点修,势能分析一下时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n) ,所以线段树上在维护个区间最大值。 - AT_abc325_g
待完善 - CF1175F The Number of Subpermutations
首先考虑到梅森旋转进行和哈希或者异或哈希很简单,问题在于要进行判断区间 [ l , r ] [l,r] [l,r] 是否是 [ 1 , r − l + 1 ] [1,r-l+1] [1,r−l+1] 的排列,我们考虑到排列肯定是从 1 1 1 开始,所以我们可以取出所有的 1 1 1 ,从 1 1 1 的两边分别去枚举数,枚举到 1 1 1 则跳出,但枚举到一个数他的排列到哪里怎么算这还是一个 O ( n ) O(n) O(n) 的东西,但实际上我们可以发现,从 1 1 1 到它的排列因该是,在原数组区间最大值(如果有比这还大的,那就肯定在那里会考虑这种情况,小于的肯定就不可能)。
这个用 1 1 1 隔开的方法时间复杂度为 O ( n ) O(n) O(n) - P8819 [CSP-S 2022] 星战
向总司令致敬!!!
我们要做忠诚于将军(bushi)总司令的(荷包零距离)观察员,先考虑何时可以反击。
不难看出只要在图是一个有向图上内向基环树森林即可反击,内向基环树森林有个美妙的性质,就是每个点的出度均为 1 1 1,所以我没就可以给每个点搞一个和哈希(点权乘初度),因为可能会删掉一些所能到达一个虫洞的边,所以为了保障每次修改查询时间复杂度 O ( 1 ) O(1) O(1) 对于一条边 u − > v u->v u−>v 我们直接在 v v v 处维护 u u u 的点权即可。
这道题还算够人性,保障操作均合法。 - P3792 由乃与大母神原型和偶像崇拜
trick题,这次让你求 [ l , r ] [l,r] [l,r] 是否是值域上连续的一段不同的数,这无非就是改成了判断该区间是否满足两个性质:- m x − m i + 1 = r − l + 1 mx-mi+1=r-l+1 mx−mi+1=r−l+1
-
[
l
,
r
]
[l,r]
[l,r] 区间上的数等于
[
m
i
,
m
x
]
[mi,mx]
[mi,mx]
又是异或哈希,但唯一的问题在于值域很大,无法一一赋值;想到离散化,但有可能 2 2 2 个原本值域上不连续的数离散化后连续;
这时可以把 a i a_i ai 和 a i + 1 a_i +1 ai+1 一起离散化就不会出现这种情况了。
- P2757 [国家集训队] 等差子序列
转换成 CF452F - CF1746F Kazaee
考虑搞和哈希,如果一个区间长度都不能被 k k k 整除,则肯定“NO”,否则我们对区间和哈希对 k k k 取模,这个哈希肯定会把“NO”误判成"YES",因为每个原数我们是随机映射的,所以原数列区间映射和对 k k k 取模一定也在 [ 0 , k − 1 ] [0,k-1] [0,k−1] 随机,只有余数为 0 0 0 时才可能把 “NO”判成"YES",概率为 1 k \frac{1}{k} k1,当 k = 2 k=2 k=2时这个概率最大,我们只要多随机几次就好了。
梅森旋转伪随机数生成算法
是目前为止随机生成数最随机的算法。
mt19937 rnd(time(0));
mt19937_64 rnd(time(0));
250306
大致安排
上午讲了 b a s e a i base^{a_i} baseai 的哈希,下午AT_abc315模拟赛,比赛打得爆炸
题目
- CF1418G Three Occurrences
区间每个数均有且仅出现 3 3 3 次,不是很好维护,所以将它分成 2 2 2 个条件分别维护:- 每个数出现次数 ≤ 3 \leq 3 ≤3
- 每个数出现次数
m
o
d
3
=
0
\mod 3=0
mod3=0
前者双指针,后者和哈希(异或哈希求得是出现次数为奇数)
- AT_abc315_a
- AT_abc315_b
- AT_abc315_c
- AT_abc315_d
(模拟) - AT_abc315_e
- AT_abc315_f
首先我就想着定义状态 f i , j f_{i,j} fi,j 表示经过前 i i i 个点,总共跳跃了 j j j 个点的最小行走距离。这题一共有 2 2 2 个关键点。- 首先跳跃次数非常的少可能不足 30 30 30 即使每次跳点都跳对角线,那么距离总和为 1 0 8 ⋅ 2 10^8\cdot \sqrt {2} 108⋅2,这也是少于 2 30 2^{30} 230
- 因为他接受一定限度的精度误差,如果在在进行 i − > j ( i < j ) i->j(i<j) i−>j(i<j) 的跳跃操作时,可能会经过 k ( k > j > i ) k(k>j>i) k(k>j>i) 而题目不允许,但实际上我们可以偏离一点点轨道,新增出来的距离是无限趋近于 0 0 0
- P5278 算术天才⑨与等差数列
方法一: b a s e a i base^{a_i} baseai 哈希,因为公差为 k k k 在执行查询操作时时间复杂度至少增加 O ( n ) O(n) O(n) ,我们可以用 b a s e a i base^{a_i} baseai 给他用等比数列搞成 O ( l o g 2 n ) O(log_2n) O(log2n)
方法二:线段树启动。
前两个都非常好搞,最后一个整个 u n o r d e r e d − m a p < i n t , s e t < i n t > > unordered-map<int,set <int> > unordered−map<int,set<int>> 去搞每个数和其相等的前驱,线段树上维护这个东西的最大值判断是否 < l < l <l 即可(这里unordered_map变相起到离散化的作用)
250307
大致安排
讲解了AT_abc315,发现g是一道裸exgcd,下午简单补了点题
题目
-
AT_abc315_g
枚举 i i i 就成了exgcd求在一定解空间内解集的数量 -
CF2071D1 Infinite Sequence (Easy Version)
注意到 2 2 2 个关键点,即可解决该题。- l = r l=r l=r
- m > n 且 m 是偶数,满足 a i = a i + 1 m>n且m是偶数,满足a_i=a_{i+1} m>n且m是偶数,满足ai=ai+1
-
P5656 【模板】二元一次不定方程 (exgcd)
无非就是在AT_abc315_g上加了点判断 -
gym105632G Same Sum
这道题区间加,区间查询能否将区间内元素两两匹配,使得每组匹配的值的和相等。
这里可以观察到一个很显然的性质:- 这个相等的值就是 2 ⋅ a v r e r a g e 2\cdot avrerage 2⋅avrerage
这道题也可以用 b a s e a i base^{a_i} baseai 去做,区间判断匹配成功即 ∑ i = l r 2 a i = 2 2 ⋅ a v r ⋅ ∑ i = l r 1 2 a i \sum_{i=l}^r 2^{a_i} = 2^{2\cdot avr} \cdot \sum_{i=l}^r \frac{1}{2^{a_i}} ∑i=lr2ai=22⋅avr⋅∑i=lr2ai1
-
CF1325E Ehab’s REAL Number Theory Problem
因数个数不超过 7 7 7 个,我们考虑一下最终的形式:- 1 1 1 个: 1 1 1
- 2 2 2 个: 1 1 1, p p p
- 3 3 3 个: 1 , p , p 2 1,p,p^2 1,p,p2
- 4 4 4 个: 1 , p , p 2 , p 3 1,p,p^2,p^3 1,p,p2,p3 ; 1 , p , q , p q 1,p,q,pq 1,p,q,pq
- 5 5 5 个: 1 , p , p 2 , p 3 , p 4 1,p,p^2,p^3,p^4 1,p,p2,p3,p4
- 6 6 6 个: 1 , p , p 2 , p 3 , p 4 , p 5 1,p,p^2,p^3,p^4,p^5 1,p,p2,p3,p4,p5 ; 1 , p , q , p q , q 2 , p q 2 1,p,q,pq,q^2,pq^2 1,p,q,pq,q2,pq2
- 7 7 7 个: 1 , p , p 2 , p 3 , p 4 , p 5 , p 6 1,p,p^2,p^3,p^4,p^5,p^6 1,p,p2,p3,p4,p5,p6
非常容易观察到,当一个数因数个数为 1 、 3 、 5 、 7 1、3、5、7 1、3、5、7 时,其本身就是完全平方数,答案为 1 1 1 。
剩下的数同一个质因数肯定出现奇数次,如果有两个可以分解为 p x p^x px 形式,答案为 2 2 2 。
之后剩下的数可以变为 p , p q p,pq p,pq 的形式,我们直接建边跑bfs最短偶环。建边方式如下:- p q pq pq, p < − > q p<->q p<−>q
- p p p,搞个虚拟源点 0 0 0, 0 < − > p 0<->p 0<−>p
Exgcd
//Exgcd 求 二元一次不定方程特解
inline void exgcd(int a,int b,int& x,int& y){
if(b==0){
x=1;
y=0;
return ;
}
exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return ;
}
250308
大致安排
上午比较摆烂,写了一道妙妙随机化,下午和Crh一队全机房VP gym105487 ICPC取得了除了老师以外第二名的好成绩,晚上又打了AT_abc396,取得了 6 7 \frac{6}{7} 76 的好成绩,爆上分。
题目
-
CF1305F Kuroni and the Punishment
妙妙随机化,首先我们要想一些特解发现一些性质:- 如果 g c d = 2 gcd=2 gcd=2,非常显然操作次数不超过 n n n
- 我们只关心 g c d gcd gcd 为质数
- 借助第一点,之多一半的数操作数绝对值 ≥ 2 \geq 2 ≥2
随机选取数列中的 30 30 30 个数,并把他们的质因数搞出来离散化,时间复杂度 O ( 30 ⋅ l o g 2 V ⋅ n ) O(30\cdot log_2{V}\cdot n) O(30⋅log2V⋅n) ,失败概率 < 1 2 30 <\frac{1}{2^{30}} <2301
-
gym105487A Box
-
gym105487C CCPC
-
gym105487H Square Root
-
gym105487L Puzzle
-
gym105487G Increasing Sequence
题目要求是对 a [ ] a[] a[] 每一位异或上 x ∈ [ 0 , k ] x\in[0,k] x∈[0,k] 使其不降的 x x x 取值方案数。
先忽略 x ∈ [ 0 , k ] x\in[0,k] x∈[0,k] 的条件,从二进制高往低考虑,序列可能在这一位表现出很多种形态:- 0……0 在 2 x 2^x 2x 有无皆可
- 1……1 同上
- 0……01……1 只能没有 2 x 2^x 2x ,序列分裂成 2 2 2 段
- 1……10……0 必须有 2 x 2^x 2x,序列分裂成 2 2 2 段
这样分治下去,对于每个二进制位的取与不取,及每个数对于这个限制的交集。
最后加上 x ∈ [ 0 , k ] x\in[0,k] x∈[0,k] 的限制即可。 -
AT_abc396_a
-
AT_abc396_b
-
AT_abc396_c
-
AT_abc396_d
-
AT_abc396_e
根据异或限制建边权为 0 / 1 0/1 0/1 进行异或转移判断矛盾的图,跑bfs -
AT_abc396_f
(太水了)
250309
大致安排
参观清华,没补题。