ios::sync_with_stdio(false);//同步流
cin.tie(0);

vector

v.insert(v.begin()+2, 1); // 指定位置,插入元素,O(n)
	vector<ll>::iterator it = find(v.begin(),v.end(),num); //返回的是一个迭代器指针,若未找到返回v.end();
rotate(v.begin(), it, v.end());
////rotate : 将v.begin() 与 v.end()之间的元素从it(it为存在与begin 和 end 间的一个迭代器)位置进行左旋转, it所指元素为旋转后的首元素
////rotate(v.begin(), v.begin() + 3, v.end());
//// 1 2 3 4 5 6
//// 4 5 6 1 2 3

string

string aa = "12345";
s.append(aa, 0, 2); // 将字符串aa第0位开始的2个字符串追加到是s尾部
aa = s.substr(0, 2); // 将字符串s从第0位开始的2个字符串赋值给aa
s.length()
s.size()
s = cin.get(); // 读入一个字符
getline(cin, s); // 读入一行
vector<string> vs; // string等都可以放入
s.find("a") // 在s中找"a"第一次出现的位置
s.find("a", 1) // 从下标1开始在s中"a"第一次出现的位置
s.find("a") == s.npos // 找不到返回npos
    
(1)s.erase(pos,n);//删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
(2)s.erase(position);//删除position处的一个字符(position是个string类型的迭代器)
(3)s.erase(first,last);//删除从first到last之间的字符(first和last都是迭代器)

set

$O(\log{size})$

#include <set>
// 集合 自动去重 自动排序 内部使用红黑树实现 插入、查找时间复杂度都是log级别的
{2, 1, 1} -> {1, 2}
set<int> s;
multiset<int> ms; // 不去重(注意删除操作) {1, 1, 2} erase(1) -> {2}
erase(iterator)
s.insert(2); // 插入元素O(1)
s.erase(2); // 删除元素
set<int>::iterator it;
for (it = s.begin(); it != s.end(); ++it) {}
set<int>::reverse_iterator rit;
rit = prev(rit)//上一个
for (rit = s.rbegin(); rit != s.rend(); ++rit) {}
for (auto v : s)
s.lower_bound(2);
s.upper_bound(2);
// 找不到会返回s.end()
s.find(2) == s.end()
s.count(2)
clear();
set<pair<ll, ll>> s;
ll a = s.lower_bound(make_pair(a, b));//先找a,再找b

set的lower_bound 比 std::lower_bound效率高很多

bitset

    bitset<4>s1(string("1001"));
    bitset<4>s2(string("0011"));
    
    cout<<s1.count()<<endl;//用于计算s1中1的个数
    cout<<s1.size()<<endl;//s1的位数
    
    cout<<s1.test(0)<<endl;//用于检查s1[0]是0 or 1并返回0 or 1
    cout<<s1.any()<<endl;//检查s1中是否有1,并返回1or0
    cout<<s1.all()<<endl;//检查s1中是否全部为1,并返回0or1
    cout<<s1.none()<<endl;//检查s1中是否全不为1,并返回0or1
 
    cout<<s1.flip(2)<<endl;//将参数位取反,0变1,1变0
    cout<<s1.flip()<<endl;//不指定参数时,每一位取反
 
    cout<<s1.set()<<endl;//不指定参数时,每一位变为1
    cout<<s1.set(3,1)<<endl;//指定两位参数时,将第一参数位的元素变为第二参数的值,第二参数位只能为0or1
    cout<<s1.set(3)<<endl;//只有一个参数时,将参数下标处变为1
 
    cout<<s1.reset(4)<<endl;//一个参数时将参数下标处变为0
    cout<<s1.reset()<<endl;//不传参数时将bitset的每一位变为0
    
    string s = s1.to_string();  //将bitset转换成string
    unsigned long a = s1.to_ulong();  //将bitset转换成unsigned long
    unsigned long long b = s1.to_ullong();  //将bitset转换成unsigned long long
    cout<<s<<endl;
    cout<<a<<endl;
    cout<<b<<endl;

merge

merge(first1, last1, first2, last2, now, cmp)//将两个  有序  的序列合并为一个  有序  的序列
    //first1 是第一个容器的首迭代器
    //last1 是第一个容器的末迭代器
    //first2 是第二个容器的首迭代器
    //last2 是第二个容器的末迭代器
    //now 合并之后要存放的容器首地址
    //cmp为比较函数, 不写cmp则默认升序

vector<ll> v;
v.resize(new size);//配合merge使用,不然会报错

iota

#include <iostream>     // std::cout
#include <numeric>      // std::iota
int main () {
  int numbers[10];
  std::iota (numbers,numbers+10,100);////从val(此处为100)开始逐个加一
  for (int& i:numbers) std::cout << ' ' << i;/////100 101 102 103 104 105 106 107 108 109
  std::cout << '\n';

  return 0;
}

位运算函数

__builtin_ctz()//返回二进制下末尾0的个数
__buitlin_ctzll()//返回二进制末尾0的个数
__buitlin_clz()//返回二进制下前导0的个数,总长32
__buitlin_clzll()//返回二进制下前导0的个数,总长64
__builtin_popcount()//返回二进制下1的个数
__builtin_ffs()//返回二进制下最后一个1的位置(最后一个位置是1)

nth_element

nth_element(v.begin(), v.begin() + k, v.end(), cmp);
将第 k 大的元素(排序后放在v.begin()+k-1上的元素)放在 v.begin()+k-1 上,前面的元素都比它小,后面的都比它大

v.erase+remove_if

bool isZero(int num){return num == 0;}
int main(){

    vector<int> v{1,2,0,3,4,0,0,5,6,7,8,9,0,0,8,0,9};
    remove_if(v.begin(),v.end(),isZero);
    for(vector<int>::iterator it = v.begin();it!=v.end();it++) cout<<*it<<"  ";
    return 0;
}
// 这里的输出为:1  2  3  4  5  6  7  8  9  8  9    9  0  0  8  0  9
//可以理解为用remove_if将容器中符合remove条件的元素移去,但容器的size不会改变。
//比如例中有6个0,最后六个位置是原序列最后六个元素,可以配合 erase 进行删除
vector<int> v{1,2,0,3,4,0,0,5,6,7,8,9,0,0,8,0,9};
v.erase(remove_if(v.begin(),v.end(),isZero),v.end());
//得到序列:1  2  3  4  5  6  7  8  9  8  9

不积跬步,无以至千里!