众所周知,longlong不开见祖宗,每年都有很多人因此而吃亏,包括我自己,long long int 的上界建议定为1e18
//万能头
#include<bits/stdc++.h>
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
lower_bound返回数组中第一个大于等于k的迭代器,upper_bound返回数组中第一个大于k的迭代器,实现为二分,使用方法如下:
int an[]:1 1 1 2 2 3 3
lower_bound(an,an+7,2)-an //为3
upper_bound(an,an+7,2)-an //为4
vector<int> an:1 1 1 2 2 3 3
lower_bound(an,begin(),an.end(),2)-an.begin() //为3
upper_bound(an,begin(),an.end(),2)-an.begin() //为4
double不够时用long double,注意printf的时候double用%.nlf,long double用%.nLf.
一个vector类型的size是unsigned long long ,如果减去一个数为负数,会发生越界,注意要强制转化
输出int时带前导0,比如
printf(“%05d”,res)
若res位数大于5,则输出res,否则前面补0输出5位
自创数据:
新创一个cpp文件:
int main() {
freopen("test.txt", "w", stdout);
cout << 1 << "\n";
return 0;
}
在代码文件里直接访问:
freopen("test.txt", "r", stdin);
set容器使用:不允许重复,不排序
struct cmp{
bool operator()(pi a,pi b) const
{
if(a.x!=b.x)
{
return a.x>b.x;//按照第一个从大到小排列
}
else{
return a.y<b.y;//第一个相等的时候按照第二个元素从小到大排列
}
}
};
set<pi,cmp> g;//也可以写成set<pi,greater<pi>> g;
g.insert({1,2});
g.insert({3,5});
g.insert({3,4});
g.insert({4,2});
g.erase({5,2});
for(auto it=g.begin();it!=g.end();it++)
{
cout<<it->x<<" "<<it->y<<"\n";
}
erase没有删除的时候不会报错
输出:
4 2
3 4
3 5
1 2
multiset容器:允许重复的set,排序
常用二维数组转化为一维:a和b必须是从0开始
int get(int a,int b)
{
return a*n+b;
}
在unordered_map中使用pair
struct pair_hash
{
template<class T1, class T2>
std::size_t operator() (const std::pair<T1, T2>& p) const
{
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
return h1 ^ h2;
}
};
map使用count来查看是否存在元素
unordered_map<pair<int, bool>, int, pair_hash> Map;
pair<int, int> res = {1, 2};
Map[res] = 3;
cout << Map.count({1, 2});
输出:1
全排列:
vector<int >a;
for (int i = 1; i <= 5; i++)
a.push_back(i);
while (next_permutation(a.begin(), a.end())) {
for (int i = 0; i < 5; i++)
cout << a[i] << " ";
cout << "\n";
}
string的substr函数:
string a=”abcd”
cout<<a.substr(0,2);
输出:从下标0开始的长度为2的子串,即“ab”
cout<<a.substr(1,3);
输出:从下标1开始的长度为3的子串,即“bcd”
结构体排序:return ture则a在b前面
struct Stone {
int s, e, l;
} stone[110];
bool cmp(const Stone a, const Stone b) {
int x = a.s * b.l;
int y = b.s * a.l;
if (x == y)
return a.e > b.e;
else
return x < y;
}
sort(an, an + n , cmp);
pair排序(使用sort)
bool cmp(pi a, pi b) {
return a.first < b.first;
}
sort(an, an + n , cmp);//从下标0到n排序,按照第一个元素从小到大排序
优先队列对结构体建立小根堆(队头为最小值)需要重载大于号
struct node {
int dist, u, type;
bool operator>(const node a) const {
return dist > a.dist;
}
};
priority_queue<node, vector<node>, greater<node>> heap;
优先队列对结构体建立大根堆(队头为最大值)需要重载小于号
struct node {
int dist, u, type;
bool operator<(const node a) const {
return dist < a.dist;
}
};
priority_queue<node, vector<node>, less<node>> heap;
注意auto修改值的时候要加&
unordered_map
初始化为bool是false
若二维数组为局部变量,各元素的值不确定。例如:一个局部变量a[4][4]未初始化值
若二维数组为全局变量,各元素的值编译器会默认初始化为0;例如:全局变量a[4][4]未初始化
结构体初始化:需要有默认形参,不然定义结构体数组会报错。
struct ddata{
int d,u,r;
ddata(int dd=0,int uu=0,int rr=0):d(dd),u(uu),r(rr){}
};
位运算
求x的二进制的第k位:
x>>k&1;
比如:10010>>3&1 为0
返回x的最后一个1:
int lowbit(int a)
{
return a&-a;
}
lowbit(x)
lowbit常用于树状数组
比如:lowbit(18):2(18为10010即返回10)
memset使用:
int:
-1 0 为本值
127为INT_MAX,0x3f为较大值,且值为0x3f3f3f3f
128为INT_MIN
double:
0x7f为最大值,0xfe为最小值
0x42为很大值,0xc2为很小值
精度问题:
使用double时候如果出现分数,可能导致相等的两个数不一样,用equal函数查看a和b是否相等:
bool equal(double a, double b) {
if (fabs(a - b) < eps)
return true;
return false;
}
大顶堆:top是最大值
#define x first
#define y second
struct cmp {
bool operator()(pi a, pi b) {
return a.x > b.x;
}
};
typedef pair<int,int> pi;
priority_queue<pi,vector<pi>,cmp> heap;
include
getline(cin, line);
string str = "hello world I am very happy!";
stringstream sstream(str);
while (sstream) {
string substr;
sstream >> substr;
cout << substr << endl;
}
输出:
hello
world
I
am
very
happy!