最近sb错误写多了,决定写一个博客来提醒自己!毕竟细节决定能否AC!持续更新!
数据范围:
可能爆int,要使用long long或者unsigned long long(_int128)
有时候题目数据没有爆int,但是可能在运算的时候爆int
数组定义多大的范围要仔细一点,可能大了就MLE,小了就RE。
数组开大开小都可能TLE,TLE返回RE也不是没有可能。
若初始化INF=0x7fffffff
,相加可能会溢出。
精度问题:
可能要把double换成long double(听说18年WF中吉利爷最后一分钟绝杀了一题,就是把double改成long double才过的)
有时候要用eps,而且eps精度的选取看题而定。但是我感觉很多时候不用eps也能过题。
比较浮点数大小的时候可以这样写:
bool dy(double x,double y) { return x - y > eps;} // x > y
bool xy(double x,double y) { return x - y <- eps;} // x < y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
数据初始化问题:
有的题目要多组输入,当你使用vector的时候一定要记得把它clear掉,因为很多人习惯把vector定义成全局变量。
防止忘掉初始化问题,建议大家写一个init()函数,把需要初始化的数组,变量或一些数据结构放里面。
数组清空不要使用memset(ar, 0, sizeof(ar));
,你可以选择:for(int i = 0; i <= n; ++i)ar[i] = 0;
或memset(ar, 0, sizeof(int)*n);
。
freopen问题:
听说有的测评姬就算你把freopen注释掉也会CE。
这时候需要你提前调戏测评姬,了解她的“习惯爱好”。
这里提供两种freopen的写法:
第一种方法在提交的oj上时,要把宏定义DEBUG给注释掉。
第二种方法可以不用注释直接交,很多oj支持这种写法(牛客网好像不能这样
#define DEBUG
#ifdef DEBUG
freopen("D:in.in", "r", stdin);
freopen("D:out.out", "w", stdout);
#endif
#ifndef ONLINE_JUDGE
freopen("D:in.in", "r", stdin);
freopen("D:out.out", "w", stdout);
#endif
vector套结构体怎么使用lower_bound
vector<lp>B[1000];
lp tmp;
bool cmp(const lp &a,const lp &b){
if(a.x==b.x)return a.id<b.id;
return a.x<b.x;
}
int p=lower_bound(B[i].begin(),B[i].end(),tmp,cmp)-B[i].begin();
注意:
cmp函数的参数一定要加const,不然会报错,我也不知道为什么。
SB问题:
比如把变量名写错了,rlg,烦
O2优化
有的oj没开o2优化,会有各种不必要的卡时问题。比如卡常啥的
提供几种加速方法:
1.使用inline,定义内联函数,不开O2优化的话,确实能快很多
2.使用max(),min()等函数会慢,你可以使用if()else来代替max或min的使用,据说使用三目运算符会快更多
3.位运算优化:
x!=-1 => ~x
x*2 => x<<1
x*2+1 => x<<1|1
x/2 => x>>1
x%2 => x&1
x%2==0 => !(x&1) //注意: ~(x&1)这是错的
x&(x-1) => 是否是2的幂次
void swap(int &x,int &y){x^=y^=x^=y;}
关闭同步流:
如果你习惯使用cin和cout,建议你在代码中加上下面这句话,会快很多
std::ios::sync_with_stdio(false);cin.tie(0);
寻址优化
定义多维数组的时候,把大的定义在前面会比较快,比如int[10000][3];
Debug:
为了方便degub,可以使用下面这个宏定义
使用cout是避免数据类型不同而造成麻烦。
#define ka getchar()
#define fuck(x) cout<<"* "<<x<<"\n"
#define debug cout<<"****\n"
下面附上祖传头文件:
/*
**链接**
传送门: [here]()
**题意**
**思路**
**备注**
*/
#define LH_LOCAL
#pragma comment(linker, "/STACK:102400000,102400000")
//#include<bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <array>
#include <map>
#include <queue>
#include <set>
#include <deque>
#include <list>
#include <bitset>
#include <complex>
#include <cassert>
#include <ctime>
#define fi first
#define se second
#define endl '\n'
#define o2(x) (x) * (x)
#define BASE_MAX 31
#define mk make_pair
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(a, b) memset((a), (b), sizeof((a)))
#define rep(i,s,t) for(register int i=s;i<t;++i)
#define per(i,s,t) for(register int i=s;i>=t;--i)
#define iis std::ios::sync_with_stdio(false);cin.tie(0)
#define my_unique(x) sort(all(x)), x.erase(unique(all(x)), x.end())
using namespace std;
#pragma optimize("-O3")
typedef long long int64;
typedef unsigned long long uint64;
typedef pair<int, int> pii;
// mt19937 rng(time(NULL));
// mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
// mt19937_64 generator(std::clock());
// shuffle(arr, arr + n, generator);
inline int64 read() {
int64 x = 0;int f = 0;char ch = getchar();
while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch =
getchar(); return x = f ? -x : x;
}
inline void write(int64 x, bool f) {
if (x == 0) {putchar('0');if (f) putchar('\n');return;}
if (x < 0) { putchar('-');x = -x;}
static char s[23];int l = 0;
while (x != 0) s[l++] = x % 10 + 48, x /= 10;
while (l) putchar(s[--l]);
if (f) putchar('\n');
}
int lowbit(int x) { return x & (-x); }
template <class T>
T big(const T &a1, const T &a2) {return a1 > a2 ? a1 : a2;}
template <class T>
T sml(const T &a1, const T &a2) {return a1 < a2 ? a1 : a2;}
template <typename T, typename... R>
T big(const T &f, const R &... r) {return big(f, big(r...));}
template <typename T, typename... R>
T sml(const T &f, const R &... r) {return sml(f, sml(r...));}
void debug_out() { cout << '\n'; }
template <typename T, typename... R>
void debug_out(const T &f, const R &... r) {
cout << f << " ";
debug_out(r...);
}
#ifdef LH_LOCAL
#define debug(...) cout << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__);
#else
#define debug(...) ;
#endif
const int HMOD[] = {1000000009, 1004535809};
const int64 BASE[] = {1572872831, 1971536491};
const int64 INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;// 998244353
const int MOD = 1e9 + 7;
const int MXN = 2e5 + 5;
const int MXE = 2e6 + 6;
void read_data() { }
void gao_solve() { }
void print_ans() { }
int main() {
#ifdef LH_LOCAL
freopen("D:in.in", "r", stdin);
freopen("D:out.out", "w", stdout);
#endif
debug(1)
read_data();
gao_solve();
print_ans();
#ifdef LH_LOCAL
// cout << "time cost:" << 1.0 * clock() / CLOCKS_PER_SEC << "s" << endl;
// system("pause");
#endif
return 0;
}
/*
clock_t a;
int t = GetTickCount();
#ifndef ONLINE_JUDGE
cout << "time cost:" << clock() << "ms" << endl;
#endif
*/
RE,TLE可能的毒瘤原因:
我以前碰到过一次超级毒瘤卡的RE的题,具体可以看这里,点击查看
vector不清空也会RE,数组小了会RE,vis[负数]也会RE。int型变量超过int的范围会RE。
数组开小了可能会TLE,检查细节,说不定那个变量名写错了就TLE了,dfs如果一直TLE就要考虑玄学剪枝。
神奇的MLE的原因!!!
自定义优先队列
priority_queue<int>Q;//默认从大到小排序
priority_queue<int,vector<int>,greater<int> >Q; //从小到大排序,最后两个<分开写
/********************************/
//我本地用的c++14编辑
struct lp{
int val,id;
friend bool operator <(const lp &a,const lp &b){
if(a.val==b.val)return a.id>b.id;
return a.val>b.val;
}
};
//这时在优先队列中值小的排在前面,值相同时id小的排在前面
priority_queue<lp>Q;
priority_queue<lp,vector<lp>,less<lp> >Q;
//有没有很奇怪,其实没什么好奇怪的,因为优先队列是优先级高的排在前面
/********************************/
//还有一种写法
struct lh{
int val,id;
friend bool operator >(const lh &a,const lh &b){
if(a.val==b.val)return a.id>b.id;
return a.val>b.val;
}
}A,BB,C;
//这时在优先队列中值小的排在前面,值相同时id小的排在前面
priority_queue<lh,vector<lh>,greater<lh> > Q;
/********************************/
/*
这东西,按自己习惯理解吧
*/
/********************************/
优先队列套pair
struct cmp{
bool operator()(pii a,pii b){
return a.first>b.first;
}
};
priority_queue<pii,vector<pii>,cmp>q;
q.push(make_pair(0,1));
一些STL:
equal_range
用于查找一个有序序列中值相等的一部分的范围
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
pair<vector<int>::iterator, vector<int>::iterator> ret =
equal_range(data.begin(), data.end(), k);
return ret.second - ret.first;
}
};
一个神奇的函数写法:
int main(int argc, char const *argv[]){
while(~scanf("%d", &n)){
function<int(int)>dfs = [&](int u){
if(u <= 1)return 1;
return u + dfs(u - 1);
};
printf("%d\n", dfs(4));
std::vector<int> v(10, -1);
for(auto x: v){
printf("%d\n", x);
}
}
return 0;
}
C++的lambda表达式
调和级数求和:
0.57721566490153286060651209 + ln(n)
long long 取模
更多信息请看:here
LL mul(LL a,LL b,LL p){
LL tmp=(a*b-(LL)((long double)a/p*b+1e-8)*p);
return tmp<0?tmp+p:(tmp>=mo?tmp-mo:tmp);
}
自定义随机数
关于随机算法更多信息请看:here
int myrand() { return rand() % 1000 * 1000000 + rand() % 1000 * 1000 + rand() % 1001; }
对拍
:again
suiji > input.txt
cpp1 < input.txt > biaoda_output.txt
cpp2 < input.txt > mytest_output.txt
fc biaoda_output.txt mytest_output.txt
if not errorlevel 1 goto again
pause
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<windows.h>
using namespace std;
int main(){
int t = 100;
while (t--){
//system("suiji > mi.in");
//system("cpp1 < mi.in > 1.out");
//system("cpp2 < mi.in > 2.out");
if (system("fc 1.out 2.out")){
printf("---\n");
break;
}
}
system("pause");
return 0;
}
获取程序运行时间
//clock_t a;
cout << "time cost:" << clock() << "ms" << endl;
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << "ms." << endl;
printf("My Time: %.4lfms\n", (double)clock() / CLOCKS_PER_SEC);
写一点其它的吧:
卡特兰数:
h(n)= h(0)*h(n-1)+h(1)h(n-2) + … + h(n-1)h(0) (n>=2)
h(n)=h(n-1)(4n-2)/(n+1);
h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,…)
出栈次序,类似问题 买票找零,凸多边形三角划分,给定节点组成二叉搜索树,括号化,n对括号正确匹配数目,特别的n个左m个右,C(n+m,m)-C(n+m,m-1)
http://www.cnblogs.com/jianglangcaijin/p/3443689.html
某大神编程优化心得:here