算法板子(持续更新中)

区间问题

线段树
#include<bits/stdc++.h>
using namespace std;
const int N=1000;

int arr[N],tree[N],lazy[N];
void build(int start,int end,int cp){
    //如果左右重合 说明到了叶子节点
    //叶子节点的值即为原数组的值
    if(start==end){
        tree[cp]=arr[start];
        return;
    }

    int lchild=cp<<1;
    int rchild=(cp<<1) +1;
    int mid=(start+end)/2;
     
    build(start,mid,lchild);//建立左子树
    build(mid+1,end,rchild);//建立右子树

    tree[cp]=tree[lchild]+tree[rchild];//维护区间和
}
//区间求和
//求区间[l,r]的和
int getSum(int l,int r,int start,int end,int cp){

    int mid=(start+end)/2;
    int lchild=cp<<1;
    int rchild=(cp<<1)+1;
    //如果有懒标记 下放
    if(lazy[cp]){
    tree[lchild]+=(mid-start+1)*lazy[cp];
    tree[rchild]+=(end-mid)*lazy[cp];
    lazy[lchild]+=lazy[cp];
    lazy[rchild]+=lazy[cp];
    lazy[cp]=0;
    }

    //无重合区域 剪枝
    if(r<start||l>end) return 0;
    //如果查询区间包含当前区间
    else if(l<=start&&end<=r) {
  
        return tree[cp];
    }
    else{
 
    int sum=0;
    //如果查询区域和当前区间的左半部分有重合,查询左子树
    if(l<=mid) 
    sum+=getSum(l,r,start,mid,lchild);
    //如果查询区间和当前区间的右半部分有重合,查询右子树
    if(r>=mid)
    sum+=getSum(l,r,mid+1,end,rchild);
    return sum;
    }

}
//区间修改 
//将区间【l,r】 每个数都加上val
void update(int l,int r,int val,int start,int end,int cp){
    
    if(l>end||r<start) return;

    else if(l<=start&&end<=r){
    
        tree[cp]+=(end-start+1)*val;
        //如果非叶子节点 打上懒标记
        if(start!=end)   lazy[cp]+=val;
    }
    else{
        int mid=(start+end)/2;
        int lchild=cp<<1;
        int rchild=(cp<<1)+1;
        if(l<=mid) update(l,r,val,start,mid,lchild);
        if(r>=mid) update(l,r,val,mid+1,end,rchild);

        tree[cp]=tree[lchild]+tree[rchild];
    }
}

二叉树

二叉树链表实现
#include<iostream>
using namespace std;

struct Tree{
    char val;
    Tree* left;
    Tree* right;
    Tree(char c=0):val(c),left(0),right(0){}
}root;

Tree* build(char c){
    if(c=='*') return 0;
    return new Tree(c);
}
Tree* search(char c,Tree* start= &root){
    if(start->val==c) return start;
    Tree* ans=0;
    if(start->left) ans=search(c,start->left);
    if(ans) return ans;
    if(start->right) ans=search(c,start->right);

    return ans;

}
Tree* pre(Tree* start){

    cout<<start->val;
    if(start->left) pre(start->left);
    if(start->right) pre(start->right);
}

搜索

深度优先遍历
int dfs(vector<vector<int>> &grid, int cur_i, int cur_j)
{
    if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1)
        return 0;
    grid[cur_i][cur_j] = 0;
    int di[4] = {0, 0, 1, -1};
    int dj[4] = {1, -1, 0, 0};
    int ans = 1;
    for (int index = 0; index != 4; ++index)
    {
        int next_i = cur_i + di[index], next_j = cur_j + dj[index];
        ans += dfs(grid, next_i, next_j);
    }
    return ans;
 }
}
广度优先遍历
int bfs(vector<vector<int>> &grid, int cur_i, int cur_j)
{
    
    grid[cur_i][cur_j] = 0;
    queue<pair<int, int>> q;
    q.push(make_pair(cur_i, cur_j));
    int ans = 1;
    while (!q.empty())
    {
        pair<int, int> x = q.front();
        q.pop();
        int di[4] = {0, 0, 1, -1};
        int dj[4] = {1, -1, 0, 0};

        for (int index = 0; index != 4; ++index)
        {
            int next_i = x.first + di[index], next_j = x.second + dj[index];
            if (next_i < 0 || next_i == grid.size() || next_j < 0 || next_j == grid[0].size || !grid[next_i][next_j])
                continue;

            grid[next_i][next_j] = 0;
            q.push(make_pair(next_i, next_j));

            ans += 1;
        }
    }

    return ans;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值