little tricks

时间秒杀一切 提交于 2020-02-27 13:07:39

浮点数比较

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<elemtype>>小根堆 - 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];
            }
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!