板子|逆序对

#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
const int maxn=5e5+5;
int n;
LL a[maxn],b[maxn];//原数组和排序后的数组 
LL ms(int l,int r){
    if(l>=r) return 0;
    int m=(l+r)>>1;//二分 
    LL t1=ms(l,m),t2=ms(m+1,r);//获得前半部分 和 后半部分 的逆序对个数 
    LL t3=0;//两边归并的逆序对个数 
    int i=l,j=m+1,p=l;//前半部分起点、终点和当前排序的编号 
    while(i<=m&&j<=r){//进行排序操作 
        if(a[i]>a[j]){//如果前部分的某个元素大于后半部分某个元素 
            b[p++]=a[j++];//排序 
            t3+=m-i+1;//因为前m元素中:i后的元素都比a[i]大,所以也比a[j]大,所以逆序对有m-i+1(包括自己)个 
        }
        else b[p++]=a[i++];//排序 
    }
    //完成剩下的归并操作 
    while(i<=m) b[p++]=a[i++];
    while(j<=r) b[p++]=a[j++];
    for(int i=l;i<=r;i++) a[i]=b[i];//将排序的值返回给a 
    return t1+t2+t3;//返回 
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    printf("%lld",ms(1,n));
    return 0;
}

转载于:https://www.cnblogs.com/saitoasuka/p/9937077.html

<think>好的,用户想了解深度优先搜索(DFS)算法的标准模板或实现代码。首先,我需要回忆DFS的基本原理。DFS是一种用于遍历或搜索树或图的算法,它尽可能深地访问节点,直到无法继续才回溯。根据之前的引用,用户提供的参考内容提到DFS通常用递归实现,每个节点访问一次,并且有指数、排列、组合等例题。 接下来,我需要确定用户的需求。他们可能正在学习算法,需要代码示例和模板来理解如何实现DFS。用户可能对递归和非递归(栈实现)两种方式都感兴趣。根据引用[1]、[2]、[3],DFS的递归方式更常见,但非递归方法也有其应用场景。 然后,我需要确保提供的代码符合用户的要求,并且正确。递归模板通常包括终止条件、处理当前节点、标记已访问、递归访问相邻节点。对于排列组合问题,回溯是关键步骤,需要撤销之前的选择。例如全排列问题,需要交换元素,递归后恢复原状。 另外,用户可能关心DFS的应用场景,比如路径查找、排列生成、连通性问题等。需要举一些例子,如二叉树遍历、全排列、图的连通分量,以帮助用户理解不同情况下的实现差异。 还要注意用户提到的LaTeX格式要求,确保数学公式正确使用$...$和$$...$$。例如,在时间复杂度部分,应该用$O(n)$这样的格式。 可能用户没有明确说明是否需要具体的例题,但根据引用中的信息,提供例题可以增强理解。例如全排列问题,可以展示如何用DFS生成所有可能的排列,并解释回溯过程。 最后,要检查代码的语法是否正确,比如Python中的缩进和函数定义。同时,确保引用标识正确添加,如引用[^1]、[^2]、[^3]的来源与用户提供的参考内容对应。 总结步骤:介绍DFS概念,提供递归和非递归模板,给出应用示例,说明时间复杂度和空间复杂度,最后生成相关问题。确保所有数学表达式格式正确,结构清晰,回答可靠。</think>### 深度优先搜索(DFS)算法模板与实现 深度优先搜索(DFS)是一种通过递归或栈实现的遍历算法,核心思想是“一路到底,回溯探索”。以下是DFS的标准模板和典型应用场景。 --- #### 1. **递归实现模板(树/图遍历)** ```python def dfs(node, visited): if node in visited: # 终止条件:已访问节点 return visited.add(node) # 标记当前节点为已访问 # 处理当前节点(例如打印或记录路径) print(node) # 递归访问相邻节点 for neighbor in node.neighbors: dfs(neighbor, visited) ``` **关键点**: - **终止条件**:节点已访问或超出边界。 - **回溯逻辑**:隐含在递归调用栈中,递归结束后自动回溯[^3]。 --- #### 2. **非递归实现(栈模拟递归)** ```python def dfs_iterative(start): stack = [start] visited = set() while stack: node = stack.pop() if node not in visited: visited.add(node) # 处理当前节点 print(node) # 将相邻节点逆序压入栈(保证顺序与递归一致) for neighbor in reversed(node.neighbors): stack.append(neighbor) ``` **关键点**: - 显式使用栈代替递归调用栈。 - 逆序添加邻居节点以保持遍历顺序一致。 --- #### 3. **典型应用示例** ##### **全排列问题(排列型DFS)** 生成数字$1,2,3$的所有排列: ```python def permutation(nums): def backtrack(path): if len(path) == len(nums): # 终止条件:路径长度等于数组长度 res.append(path.copy()) return for num in nums: if num not in path: # 剪枝:避免重复选择 path.append(num) backtrack(path) # 递归 path.pop() # 回溯:撤销选择 res = [] backtrack([]) return res ``` **输出**: $$[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]$$ **说明**:通过`path.pop()`实现回溯,时间复杂度为$O(n \cdot n!)$[^2]。 --- #### 4. **时间复杂度与空间复杂度** - **时间**:取决于问题结构。对于$n$个节点的树,一般为$O(n)$;对于全排列问题为$O(n!)$。 - **空间**:递归深度最大为$O(n)$,栈空间同理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值