little tricks
浮点数比较
const double eps = 1e-8;
equal : fabs(a,b) < eps
select sort
for(int i =0; i < n; i++{
int k = i;
for(int j = i; j< n; j++){
if(A[j] < A[k]) k = j;
swap(A[k],A[i])
insert sort
void insert_sort(int A[], int n){
for(int i = 1; i< n; i++){
int tmp = A[i], j = i;
while(j > 0 && A[j-1] >tmp){
A[j] = A[--j];
}
A[j]= tmp;
}
}
binary_search
int binary_search(int A[], int left, int right, int val){
int mid;
while(left < right){
mid = left + (right - left)>>1;//移位
if(A[mid]>= val)right = mid -1;//
else left = mid +1;
}
return (A[left] == val)? left: -1;
lower_bound:找第一个>= val 的值位置,即lower_bound
int lower_bound(int A[], int left, int right, int val){
int mid;
while(left < right){
mid = left + (right - left)>>1;
if(A[mid]>= val)right = mid;
else left = mid +1;
}
return (A[left] == val)? left: -1;
upper_bound:找第一个> val 的值位置,即lower_bound
int upper_bound(int A[], int left, int right, int val){
int mid;
while(left < right){
mid = left + (right - left)>>1;
if(A[mid]> val)right = mid;//
else left = mid +1;
}
return (A[left] == val)? left: -1;
so template is coming
- 左闭右闭
int bound(int A[], int left, int right){
int mid;
while(left < right){
mid = left + (right - left)>>1;
if(条件成立)right = mid;
else left = mid +1;
}
return left;
- 左闭右开
int bound(int A[], int left, int right){
int mid;
while(left < right){
mid = left + (right - left)>>1;
if(条件成立)right = mid;
else left = mid;//操作不一样了
}
return right;//返回不一样了
partition
partition(int A[], int l, int r){
int temp = A[l];
while( l < r){
while(l < r && A[r] > tmp)r--;
A[l] = A[r];
while(l < r && A[l] <= tmp) l++;
A[r] = A[l];
}
A[l] = temp;
return left;
}
gcd
int gcd(int a, int b){
return !b? a :gcd(b, a%b);
}
prime
bool isprim(int n){
if( n<= 1) return false;
int sqr = (int)sqrt(n);
for(int i = 0; i< = sqr; i++){
if(n % i == 0)return false;
}
return true;
}
n!中p质因子个数
int cal (int n, int p){
int ans = 0;
while(n){
ans += n/p;
n /= p;
}
return ans;
}
comparison重载
- off-class
bool comp(const node& a, const node &b){
return ;
}
- in-class
static bool comp(const node& a, const node &b){
return ;
}
- enbed-class
class compare(){
bool operater() (const node& a, const node&b){
return ;
}
}comp;
``
- vector, string, deque可以sort
- set 自然有序且无重复
- priority_queue <greater
>小根堆 - vector: insert(it,v), erase(it), erase(first, last), clear,size,push_back(v), pop_back(v),
- set: insert(v), erase(it), erase(first, last), erase(v), find(v),
``
union find
- init
for(int i = 0; i< n; i++){
fa[i] = i;
}
- findfa
int findfa(int x){
while(x != fa[x]){
x = fa[x];
}
return x;
}
int findfa(int x){
if( x == fa[x])return x;
else return findfa(fa[x]);
}
- union
void union (int a, int b){
int faa = findfa(a);
int fab = findfa(b);
if(faa != fab)
fa[faa] = fab;
}
- path 压缩
int findfa(int x){
int a = x;
while(x != fa[x])
x = fa[x];
while(a != fa[a]){
int z = a;
a = fa[a];
fa[z] = x;
}
return x;
}
DP
- 最大连续子序列和
dp[i] = max(dp[i-1] + A[i], A[i])
- 最长不下降子序列
dp[i] = max(dp[j]+1, 1) 【j < i】
- 最长公共子序列
dp[i][j] = dp[i-1][j-1] + 1; A[i] == B[j]
= max(dp[i-1][j], dp[i][j-1]) A[i] != B[j]
- 最长回文串
dp[i][j] = dp[i+1][j-1] + 1; s[i] == s[j]
= 0 s[i] != s[j]
遍历子串长度,遍历子串起点
- dfs
dfs(u){
vis[u] = true;
for(each v can arrive from u){
if(vis[v] == false)dfs(v)
}
}
dfstra(G){
for(v in G){
if(vis[v] == false)dfs(v);
}
}
- bfs
bfs(& q){
while(!q.empty()){
u = q.top(); q.pop();
for(each v can arrive from u){
if(vis[v] == false){
q.push_nack(v);
vis[v] = true;
}
}
}
}
bfstra(G){
for(v in G){
if(vis[v] == false){
queue q;
q.push_back(v);
vis[v] = true;
bfs(q);
}
}
}
- dij
n 图中点数
d[n] 图中点到起点距离
g[][] 地图
void dij(int s){
fill(d, d+ maxv, INF);
d[s] = 0;
for(int i = 0; i< n ; i++){
int u = -1, MIN= INF;
for(int j =0; j< n; j++){
if(vis[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
if(u == -1)return ;
vis[u] =true;
for(int v = 0; v < n ;v++ ){
if(vis[v] == false && g[u][v] != INF && d[u] +g[u][v] < d[v]){
d[v] = d[u] +g[u][v];
}
}
}
}
- prim
n 图中点数
d[n] 图中点到起点距离
g[][] 地图
void prim(int s){
fill(d, d+ maxv, INF);
d[s] = 0;
int ans = 0;// attention, 最小生成树边权值之和
for(int i = 0; i< n ; i++){
int u = -1, MIN= INF;
for(int j =0; j< n; j++){
if(vis[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
if(u == -1)return ;
vis[u] =true;
ans += d[u];
for(int v = 0; v < n ;v++ ){
if(vis[v] == false && g[u][v] != INF && g[u][v] < d[v]){
d[v] = g[u][v];
}
}
}
}