算法区
树状数组
树状数组相较于二叉树删除了一些节点,注意到第一行删除的为偶数节点,而2存储的是1和2下面的节点的合(为其叶子节点),同时我们观察到每一层的节点等同于以其为根节点的叶子节点的合,而求这些节点全体的目标合使用不到的内容就会被删掉,剩下下面的节点共有n个,刚好和最初的数组大小相等。
我们可以观察到每层节点对应的末尾零的数量和层数相关,第n(从0开始)层对应二进制末位n个零。
前置知识lowbit :这代表将非负整数转换为二进制数然后取最低位1及其后面的0组成的数
int lowbit(x) {
return x&(-x);
} //这代表将非负整数转换为二进制数然后取最低位1及其后面的0组成的数
//如11100则为100
单点修改add:修改某一点的值,其对应后面的值也都会发生改变
我们发现每次改变某一个数组中的数据下x的值,对应的x+lowbit(x)的数值也会发生改变,如当改变t[1]的值,对应t[2],t[4],t[8]的值都会对应改变
//大多数用于前缀和,通常由t[i]代表
int add(int x,int k)//单点修改更新父节点
{
for(int i=x;i<=n;i+=lowbit(i))
{
t[i]+=k;//每个数据对应+k
}
}
区间查询ask:进行区间查询,查询某一区间的sum
我们发现sum[7]=t[7]+t[6]+t[4] ,我们进一步发现,6=7-lowbit(7),4=6-lowbit(6),所以我们可以通过不断的-lowbit操作来实现求和
int ask(x){
int sum = 0;
for(int i=x;i;i-=lowbit(i)){
sum+=t[i];
}
return sum;
}
求[L,R]之间的区间合,等同于求[1,R]-[1,L-1]
int search(int L,int R)
{
int ans = 0;
ans = ask(R)-ask(L-1);
return 0;
}
函数区
1.队列
定义:队列属于容器,允许先进先出,像排队一样
queue <Type> q;
//检测对列是否为空,空返回1,非空返回0
q.empty();
//返回队列中的元素数量
q.size();
//返回队首元素
q.front();
//返回队尾元素
q.back();
//队尾添加元素
q.push();
//移除队首元素
q.pop();
2.字符串
string str;//定义空字符串
string str = "Hello,i'm wjm";//初始化
string str = str1+str2;//将str1,str2连接起来复制给str
常用函数
下述pos代表指针
size() | 返回字符串的长度(字符数)。 | cout << str.size(); |
length() | 与 size() 相同,返回字符串的长度。 | cout << str.length(); |
empty() | 判断字符串是否为空。 | cout << (str.empty() ? "Yes" : "No"); |
operator[] | 访问字符串中指定位置的字符。 | cout << str[0]; |
at() | 访问字符串中指定位置的字符(带边界检查)。 | cout << str.at(0); |
substr() | 返回从指定位置开始的子字符串。 | string sub = str.substr(0, 5); |
find() | 查找子字符串在字符串中的位置。 | cout << str.find("sub") << endl; |
rfind() | 从字符串末尾开始查找子字符串的位置。 | cout << str.rfind("sub") << endl; |
replace() | 替换字符串中的部分内容。 | str.replace(pos, length, "new_substring"); |
append() | 在字符串末尾添加内容。 | str.append(" more"); |
insert() | 在指定位置插入内容。 | str.insert(pos, "inserted"); |
erase() | 删除指定位置的字符或子字符串。 | str.erase(pos, length); |
clear() | 清空字符串。 | str.clear(); |
data() | 返回指向字符数据的指针(C++11 及之后的版本)。 | const char* data = str.data(); |
compare() | 比较两个字符串。 | int result = str.compare("other"); |
find_first_of() | 查找第一个匹配任意字符的位置。 | size_t pos = str.find_first_of("aeiou"); |
find_last_of() | 查找最后一个匹配任意字符的位置。 | size_t pos = str.find_last_of("aeiou"); |
find_first_not_of() | 查找第一个不匹配任意字符的位置。 | size_t pos = str.find_first_not_of("aeiou"); |
find_last_not_of() | 查找最后一个不匹配任意字符的位置。 | size_t pos = str.find_last_not_of("aeiou"); |
3.map
map中存储的为键值对,也就是一个关键字对应一个value
定义方式
map<数据类型1,数据类型2> 容器名
我们还可以使用 容器名[关键字] 来对值进行查找
map<string,int> wjm;
wim.insert({'kkk',0});
wjm['kkk'] = 1;
此代码可以将原本为0的wjm['kkk']改为1,主义insert函数在wjm中存在相同键值对的时候不会进行插入操作
而且map的大部分函数均可以参考字符串中的函数
一些常用的使用(C++)
格式化
cin.get() 从键盘读入一个字符,可以读入逗号之类的
int(a) 强制类型转换
cout输出左侧补0:
cout<<setw(位数)<<setfill('0')<<变量;
cout输出右侧补0:
cout<<setiosflags(ios::fixed)<<setprecision(位数)<<变量<<endl;
printf动态调整输出格式
printf("%*.*f %*.*f",a,b,变量,a,b,变量);
//这两个星号代表所要规范的位数,对应a,b
cin.get(字符数组,读入字符数量);
note:此方法可以读入含有空格和Tab的字符串
数学计算
1.幂函数 pow(数,指数)
note:若要开方的话,后面要用小数
常识区
c++中10^0 = 10;
^不是幂运算符,而是按位与
方法区
1. 验证一个数是否是整数
使用求出该数的式子往回进行带入,若正确则可验证是整数