字符串哈希
str = “ABCABCDEYXCACWing”
H[0]=0
H[1]=“A”
H[2]=“AB”
H[3]=“ABC”
思路,我们可以把字符串转换成一个数字。最后我们把整个数字对Q取模。把最终的数字映射到从0~Q-1 的一个数。
注意:不能把一个字符映射成0,比如A=0;那么AA,AAA,都是0 这样会引起冲突
整个算法是基于人品足够强。不存在冲突的情况下来考虑的。
经验值:p=131,或者=13331,Q=2^64
此外,我们可以利用所有前缀的哈希求得字串的哈希。
小技巧:直接使用unsignlong long 来存储最终的结果,我们就不需要取模了,因为溢出就相当于取模。
例题:ACWing841
#include<iostream>
using namespace std;
const int N=100010;
typedef unsigned long long ULL;
ULL p[N];
ULL h[N];
ULL q = 131;
char str[N];
ULL judge(int l,int r){
return h[r]-h[l-1]*p[r-l+1];
}
int main(){
int n;
cin>>n;
int m;
cin>>m;
cin>>str+1;
p[0]=1;
for(int i=1;i<=n;++i){
p[i]=p[i-1]*q;
h[i]=h[i-1]*q+str[i];
}
while(m--){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
if(judge(l1,r1)==judge(l2,r2)){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
return 0;
}
vector的基本用法
vector a(10,3) 定义一个长度为10的数组,里面每个数长度都是3
a.empty()判断A是否为空。
a.clear() 清空所有元素
用迭代器来遍历vector
for(vector::iterator i =a.begin();i!=a.end();++i)cout<<*i<<" ";
cout<<endl;
for(auto x: a)cout<<x<<" ";
pair<int,string> p
p.first:第一个元素
p.second:第二个元素
支持比较运算
以first为第一关键字,以second为第二关键字。
pair的初始化:
p = make_pair(10,“yxc”)
p={20,“abc”}
string
string a=“”;
a+=c;
size()
empty()
substr(起始位置,长度); 返回的是某个子串,
c_str() 返回的是调用的字符串的字符数组的起始地址。
queue
empty()
push() //向队尾队列中插入一个元素
front()//返回对头元素
back()//返回队尾元素
pop()//弹出队头元素
priority_queue 优先队列,默认是大根堆
push()
top()
pop()
如何实现小根堆?俩种方法。
一种是创建的时候直接插入-x即可。
另一种方式是定义的时候直定义成小根堆。
priority_queue<int,vector,greater>heap;
stack
push()//向栈顶插入一个元素
top()//返回栈顶元素
pop()//弹出栈顶元素
empty()
size()
deque 双端队列(加强版vector)
size()
empty()
clear()
front()
back()
push_back()//队尾插入
pop_back()//队尾弹出
push_front()//向队首插入元素
pop_front()//队首弹出
begin()/end()
set/multiset
set里面不可以有重复元素
支持:
size()
empty()
clear()
multiset里面可以有重复元素
insert()
find()查找一个数
count()返回的是某个数的个数
erase()
(1)输入是一个数,删除所有x
(2) 输入一个迭代器,删除一个迭代器
lower_bound()/uper_bound()
lower_bound(x)返回的是大于等于x的最小数的迭代器
uper_bound(x)返回的是大于x的最小数的迭代器
map,multimap
insert() 插入的是一个pair
erase()传入的参数是pair或者是迭代器
find()
[]
例如:
map<string,int>a
a[“yxc”]=1;
cout<<a[“yxc”]<<endl;
bitset,压位
就是每个字节存储八位,比正常的数组减少八倍的内存
bitset<1000>s;
~,&,|,^,>>,<<,==,!=,count()返回有多少个1,any/none()
any()判断是否至少有一个1
none()判断是否全为0
set(),把所有位置置1
set(k,v) 将第K位变为V
reset()把所有位变成0
flip()把所有位置取反等价于~
flip(k)把第k位取反。