<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://www.33dai.wiki/index.php?action=history&amp;feed=atom&amp;title=%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C</id>
	<title>字符串哈希 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://www.33dai.wiki/index.php?action=history&amp;feed=atom&amp;title=%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C"/>
	<link rel="alternate" type="text/html" href="https://www.33dai.wiki/index.php?title=%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C&amp;action=history"/>
	<updated>2026-05-07T08:25:17Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://www.33dai.wiki/index.php?title=%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C&amp;diff=177&amp;oldid=prev</id>
		<title>33DAI：​创建页面，内容为“== 一些好用的语法知识 ==  * [http://cpp.33dai.cn/reference/zh/cpp/string/basic_string/substr.html s.substr(pos, count)] ** 返回子串 [pos, pos+count) 。若请求的字串越过字符串的结尾，即 count 大于 size() - pos （例如若 count == npos ），则返回的子串为 [pos, size()) 。 ** 可以不写第二个参数，&lt;code&gt;s.substr(pos)&lt;/code&gt; 会返回子串 [pos, size())。 * 【C++11起】：[http://cpp.33dai.cn/reference/zh/cpp/co…”</title>
		<link rel="alternate" type="text/html" href="https://www.33dai.wiki/index.php?title=%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C&amp;diff=177&amp;oldid=prev"/>
		<updated>2026-05-07T03:10:15Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“== 一些好用的语法知识 ==  * [http://cpp.33dai.cn/reference/zh/cpp/string/basic_string/substr.html s.substr(pos, count)] ** 返回子串 [pos, pos+count) 。若请求的字串越过字符串的结尾，即 count 大于 size() - pos （例如若 count == npos ），则返回的子串为 [pos, size()) 。 ** 可以不写第二个参数，&amp;lt;code&amp;gt;s.substr(pos)&amp;lt;/code&amp;gt; 会返回子串 [pos, size())。 * 【C++11起】：[http://cpp.33dai.cn/reference/zh/cpp/co…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 一些好用的语法知识 ==&lt;br /&gt;
&lt;br /&gt;
* [http://cpp.33dai.cn/reference/zh/cpp/string/basic_string/substr.html s.substr(pos, count)]&lt;br /&gt;
** 返回子串 [pos, pos+count) 。若请求的字串越过字符串的结尾，即 count 大于 size() - pos （例如若 count == npos ），则返回的子串为 [pos, size()) 。&lt;br /&gt;
** 可以不写第二个参数，&amp;lt;code&amp;gt;s.substr(pos)&amp;lt;/code&amp;gt; 会返回子串 [pos, size())。&lt;br /&gt;
* 【C++11起】：[http://cpp.33dai.cn/reference/zh/cpp/container/unordered_set.html unordered_set&amp;lt;T&amp;gt;]：&amp;lt;code&amp;gt;insert&amp;lt;/code&amp;gt; 时会把 T 类型元素哈希后放入集合，搜索、插入和移除拥有平均常数时间复杂度。&lt;br /&gt;
* 【C++11起】：[http://cpp.33dai.cn/reference/zh/cpp/container/unordered_map.html unordered_map&amp;lt;T,T&amp;gt;]：略&lt;br /&gt;
&lt;br /&gt;
== 哈希基础 ==&lt;br /&gt;
&lt;br /&gt;
=== 整串哈希到整数 - 单哈希 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const long long MOD = 1000000007;&lt;br /&gt;
const int P = 29;&lt;br /&gt;
long long getHash(const string &amp;amp;s)&lt;br /&gt;
{&lt;br /&gt;
    long long hash = 0;&lt;br /&gt;
    for (int i = 0; i &amp;lt; s.length(); i++)&lt;br /&gt;
        hash = (hash * P + s[i]) % MOD;&lt;br /&gt;
    return hash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 整串哈希到整数 - 双哈希 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const long long MOD1 = 1000000007, MOD2 = 998244353;&lt;br /&gt;
const int P1 = 29, P2 = 31;&lt;br /&gt;
pair&amp;lt;long long, long long&amp;gt; getHash(const string &amp;amp;s)&lt;br /&gt;
{&lt;br /&gt;
    long long hash1 = 0;&lt;br /&gt;
    long long hash2 = 0;&lt;br /&gt;
    for (int i = 0; i &amp;lt; s.length(); i++)&lt;br /&gt;
    {&lt;br /&gt;
        hash1 = (hash1 * P1 + s[i]) % MOD1;&lt;br /&gt;
        hash2 = (hash2 * P2 + s[i]) % MOD2;&lt;br /&gt;
    }&lt;br /&gt;
    return make_pair(hash1, hash2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 整串哈希到整数 - 自然溢出哈希 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const int P = 29;&lt;br /&gt;
unsigned long long getHash(const string &amp;amp;s)&lt;br /&gt;
{&lt;br /&gt;
    unsigned long long hash = 0;&lt;br /&gt;
    for (int i = 0; i &amp;lt; s.length(); i++)&lt;br /&gt;
        hash = hash * P + s[i];&lt;br /&gt;
    return hash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 子串哈希 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Hash&lt;br /&gt;
string s;&lt;br /&gt;
const long long MOD = 1000000007;&lt;br /&gt;
const int P = 29;&lt;br /&gt;
long long myHash[30005];&lt;br /&gt;
long long powP[30005];&lt;br /&gt;
// 初始化 s[1]~s[n] 的前缀哈希&lt;br /&gt;
void initHash(int n)&lt;br /&gt;
{&lt;br /&gt;
    powP[0] = 1;&lt;br /&gt;
    for (int i = 1; i &amp;lt;= n; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myHash[i] = (myHash[i - 1] * P + s[i] - &amp;#039;a&amp;#039; + 1) % MOD;&lt;br /&gt;
        powP[i] = powP[i - 1] * P % MOD;&lt;br /&gt;
    }&lt;br /&gt;
    powP[n + 1] = powP[n] * P % MOD;&lt;br /&gt;
}&lt;br /&gt;
// 获取 s[l]~s[r] 的哈希值&lt;br /&gt;
int getHash(int l, int r)&lt;br /&gt;
{&lt;br /&gt;
    return (myHash[r] - myHash[l - 1] * powP[r - l + 1] % MOD + MOD) % MOD;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 循环节判断 ==&lt;br /&gt;
&lt;br /&gt;
如果 &amp;lt;code&amp;gt;s[1 ~ n-len] == s[len+1 ~ n]&amp;lt;/code&amp;gt;，那么 &amp;lt;code&amp;gt;s[1~len]&amp;lt;/code&amp;gt; 是一个循环节。&lt;/div&gt;</summary>
		<author><name>33DAI</name></author>
	</entry>
</feed>