[DP][分治] 51Nod 1934 受限制的排列

51nod 1934 受限制的排列 分治+数学 题意 对于一个 1 到 n 的排列 p1,p2,⋯,pn ,我们可以轻松地对于任意的 1≤i≤n 计算出 (li,ri) ,使得对于任意的 1≤L≤R≤n 来说 min(pL,pL+1,⋯,pR)=pi 当且仅当 li≤L≤i≤R≤ri 。 给定整数 n 和 (li,ri) (1≤i≤n) ,你需要计算有多少种可能的 1 到 n 的排列 p1,p2,⋯,pn 满足上述条件。 由于答案可能很... 阅读详情

SolutionSolution

一个显然的想法就是去找最小的那个数。
最小的数的 ll 和 r 就应该是 11 和 n 。
因为这是一个排列,我们把问题从最小值处 pospos 分开,得到两个一样的问题 (1,pos−1)(1,pos−1) 和 (pos+1,n)(pos+1,n) 。设区间长度为 lenlen ,分出的两个区间长度为 lenl,lenrlenl,lenr ,贡献就是这两个问题的答案的积乘上 (len−1lenl)(len−1lenl) 。
找最小值可以暴力用 mapmap 存下来就好啦~
O(nlogn)O(nlog⁡n) 。
题解的说法是这是个笛卡尔树。。吧

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;

typedef long long ll;
typedef pair<int, int> pairs;
const int N = 1010101;
const int MOD = 1000000007;

inline char get(void) {
    static char buf[100000], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, 100000, stdin);
        if (S == T) return EOF;
    }
    return *S++;
}
template<typename T>
inline int read(T &x) {
    static char c; x = 0; int sgn = 0;
    for (c = get(); c < '0' || c > '9'; c = get()) {
        if (c == '-') sgn = 1;
        if (c == EOF) return 0;
    }
    for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
    if (sgn) x = -x; return 1;
}

int n, test;
int l[N], r[N];
int fac[N], ifac[N];
map<int, int> mp[N];

inline void pre(int n) {
    ifac[1] = 1;
    for (int i = 2; i <= n; i++)
        ifac[i] = (ll)(MOD - MOD / i) * ifac[MOD % i] % MOD;
    fac[0] = ifac[0] = 1;
    for (int i = 1; i <= n; i++) {
        fac[i] = (ll)fac[i - 1] * i % MOD;
        ifac[i] = (ll)ifac[i - 1] * ifac[i] % MOD;
    }
}
inline int C(int n, int m) {
    return (ll)fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}
inline int solve(int dl, int dr) {
    if (dl > dr) return 1;
    int pos = mp[dl][dr];
    if (dl == dr && pos == dl) return 1;
    if (pos < dl || pos > dr) return 0;
    int res = (ll)C(dr - dl, pos - dl) * solve(dl, pos - 1) % MOD * solve(pos + 1, dr) % MOD;
    return res;
}

int main(void) {
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    pre(1000000);
    while (read(n)) {
        ++test;
        for (int i = 1; i <= n; i++) read(l[i]);
        for (int i = 1; i <= n; i++) read(r[i]);
        int f = 1;
        for (int i = 1; i <= n; i++) {
            if (mp[l[i]].count(r[i])) f = 0;
            mp[l[i]][r[i]] = i;
        }
        if (f) printf("Case #%d: %d\n", test, solve(1, n));
        else printf("Case #%d: 0\n", test);
        for (int i = 1; i <= n; i++) mp[i].clear();
    }
    return 0;
}
[dp优化]个人对dp优化的理解 动态规划优化 矩阵乘法 单调队列 斜率优化 决策单调性 四边形不等式 阅读详情

相关推荐

瑞萨RA6M4平台I2C驱动移植实战:MPU6050传感器集成指南

本文详细介绍了在瑞萨RA6M4平台上进行I2C驱动移植并集成MPU6050传感器的实战指南。通过FSP配置工具添加I2C主栈,适配MPU6050官方驱动,实现传感器数据读取与调试,为嵌入式开发提供完整的解决方案。

banana的博客 109

[杂题 组合] 51Nod1934 受限制的排列

不难的题。首先考虑 11 的区间一定是 [1,n][1,n]。其他数的区间不可能跨过 11 ,所以数列就分成了左右独立两边,继续找两边最小的,分下去。 显然就是一个笛卡尔树的构建过程。 设 f(L,R)f(L,R) 表示这个区间的方案数,x表示控制区间为 [L,R][L,R] 的数的位置,则: f(L,R)=f(L,x−1)∗f(x+1,R)∗(R−LR−x) f(L,R)=f(L,x-1)*

Lynstery's blog 539

金蝶ERP元数据解析:字段属性与表结构映射实战

本文深入解析金蝶ERP元数据的核心价值与应用实践,详细介绍了字段属性与表结构映射的关键技术。通过缓存获取与工具类直连两种方案对比,结合实际案例展示元数据在数据库校验、动态表单生成等场景的应用,帮助开发者高效解决二次开发中的常见问题。

weixin_33738555的博客 433

C++最难的十种排序算法【学不会私信我】(上)

当谈到排序算法时,我们经常会提到一些著名的算法,比如快速排序、归并排序和插入排序等。然而,在排序算法的世界里,还存在一些更为复杂和挑战性的算法。在本文中,我将向你介绍十种被认为是最难的排序算法。这些算法不仅在实现上具有一定的复杂性,而且在处理大规模数据集时,其时间复杂度可能非常高。让我们一一来看。

浪子回头 1180

避坑指南:C#调用CodeSoft打印标签时常见的5个错误及解决方法

本文总结了C#调用CodeSoft打印标签时常见的5个核心错误及解决方案,涵盖环境配置、模板加载、变量赋值、打印机切换和资源管理。重点解析了如何避免COM对象创建失败、模板路径错误、变量名不匹配、打印机切换异常及内存泄漏等问题,帮助开发者实现稳定高效的标签打印集成。

weixin_29215815的博客 223

opencode : 无法将“opencode“项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方案

opencode命令识别问题与openclawcodexgemini确保的路径在 PATH 中。这个知识对所有 npm 全局工具通用。

一键难忘的博客 4518

51nod 1934 受限制的排列——笛卡尔树

题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1934 根据给出的信息,可以递归地把笛卡尔树建出来。一个点只应该有 0/1/2 个孩子,不然就是无解。 dp[ cr ] 表示把 1~siz[cr] 填进 cr 这个子树的方案数。那么 \( dp[cr]=C_{siz[cr]-1}^{siz[ls]}*dp[ls]*dp[r...

weixin_34356138的博客 169

STM32电机PID速度控制

2.3 STM32电机PID速度控制 之前的文章,完成了直流减速电机的PWM控制、电机测速。本篇文章,将实现电机的速度闭环控制。 在公众号:小白学移动机器人,发送:速度PID,即可获得本篇文章的STM32工程文件以及相关资料。 2.3.1 解决的问题 解决带编码器直流电机的速度闭环问题。 2.3.2 PID理论 将偏差的比例、积分、微分,通过线性组合构成控制量,用控制量对被控对象进行控制,这样的控制器称为PID控制器。在连续空间中,我们通常探讨模拟PID的控制原理,如图所示: 我们这里用电机速度控制为例,

「小白学移动机器人」一个专注分享移动机器人相关知识的公众号! 6万+

分治&DP

分治的思想就是将大问题转化为小问题,通过小问题的求解,最终整合后成为大问题的解。做分治的题的时候,首先要分析题目,明确这道题是不是能够有降低规模求解。

任杰的博客 1924

华为OD机考真题 新系统 - 数列求值(Java/Py/C/C++/Js/Go)

华为OD机试真题 新系统【数列求值】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【数列求值】多语言题解。

qq_45776114的博客 662

沁恒CH32V30X学习笔记02--GPIO的使用教程及2次封装驱动

刚复位后,GPIO 口运行在初始状态,这时大多数 IO 口都是运行在状态所有的 GPIO 口都可以被配置外部中断输入通道,但一个外部中断输入通道最多只能映射到一个GPIO 引脚上,且外部中断通道的序号必须和 GPIO 端口的位号一致,,两方都是一对一的关系。复用功能。

Car12 705

分治&dp,LeetCode 894. 所有可能的真二叉树

从分治到dp

EQUINOX1的博客 884

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

动态规划(六)——分治优化DP 算法设计与分析 国科大

本文内容紧接动态规划(五),讨论如何优化序列对齐算法。

xiaolaji600的博客 1503

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

51NOD 1934:受限制的排列——题解

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1934 听说会笛卡尔树的人这题都秒了啊…… 参考:https://blog.youkuaiyun.com/vectorxj/article/details/79475244 首先题得看懂(我就是看题解才看懂题面的……),它告诉你对于i,我们有最大的(li,ri)使得这个区间内pi...

weixin_34292959的博客 188

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

动态规划(Dynamic Programming, DP)和分治法(Divide and Conquer, D&C)

分治法是一种将问题分解为多个独立的子问题,递归地解决这些子问题,然后将子问题的解合并以得到原问题的解的方法。它的核心思想是将问题分解为子问题,并将子问题的解存储起来(通常通过。动态规划通过存储子问题的解,避免了重复计算,适用于具有重叠子问题和最优子结构的问题。:通过迭代的方式从最小的子问题开始,逐步构建更大的问题的解。:问题可以分解为多个子问题,而这些子问题会被多次重复计算。:问题的最优解可以通过子问题的最优解来构造。从最小的子问题开始,逐步构建更大的问题的解。问题:是否可以用最少数量的硬币凑出目标值?

2302_77481882的博客 848

cdq 分治优化 dp

upd:原来的 cdq 分治内容太多了,于是考虑将 dp 部分分离出来。cdq 分治,其具有一个log就能搞定一维的优美性质,适用于一些带有偏序条件的 dp 转移式。

m0_60506105的博客 525

DP 详解

DP 问题在 OIer 中很受欢迎,因为每个 DP 问题在某种意义上都是原创的,你必须努力思考其状态和状态转移方程才能为其发明解决方案。由于动态规划如此受欢迎,它可能是算法竞赛中最重要的掌握方法。DP(Dynamic programming,全称动态规划),是一种基于分治,将原问题分解为简单子问题求解复杂问题的方法。动态规划的耗时往往远少于朴素(爆搜)解法。很简单的名字,即为使用空间的代价来确保不会超时。分类讨论就是分类 --> 讨论!

George110915的博客 6422

分治、贪心与DP

分治法 分治法顾名思义就是分而治之。一个问题能够用分治法求解的要素是:第一,问题能够按照某种方式分解成若干个规模较小、相互独立且与原问题类型相同的子问题;第二,子问题足够小时可以直接求解;第三,能够将子问题的解组合成原问题的解。由于分治法要求分解成同类子问题,并允许不断分解,使问题规模逐步减小,最终可用已知的方法求解足够小的问题,因此,分治法求解很自然导致一个递归算法 分治法的三个步骤 一般...

amf12345的博客 832

HUD1003关于分治法及DP思想的初步认识,宁品品!

HUD1003关于分治法及DP思想的初步认识,宁品品!问题示例枚举法分治法DP思想 今天刚刚开始做hdu的题,做到第三道就发现不对劲了- -,这道题刚开始感觉无从下手(主要是我太菜),然后去网上搜了下,发现小东西还真有丶东西,用分治法可以做出来的题试着用DP思想做的话简直不要太简单,刷新我这个菜鸡的世界观了。 问题 题目链接 点我点我 Given a sequence a[1],a[2],a[3]...

An_dy_code的博客 634

[2017纪中10-27]图 分治+DP

题面 首先发现总左往右考虑l到r的边,从u走到v的最小代价,相当于从右往左考虑r到l的边,从v走到u的最小代价。 于是支持从某条边向两边拓展,考虑离线分治。 假设当前在处理分治区间[L,R],设 mid=(L+R)/2,询问区间跨过了 mid 的询问就可以求解,用 DP 得到 lef[i][x][y]表示从 x 出发,处理了从 i 到 mid 的边之后到达 y 的最小代价,以及 rig[i][

DOFYPXY的博客 519

算法训练之DP小结(分治 + 最优子结构)

DP(分治 + 最优子结构) 本质上来说,是找最近最简方法,利用数学归纳法的思维,将问题拆解为可重复解决的子问题,寻找其最优子结构。 1. 格外需要注意的技巧 利用缓存(状态的存储数组)剪枝 淘汰次优解 2. 实现方式 自顶向下:递归 + 记忆化搜索 自底向上:循环递推 3. DP关键点 最优子结构 cpp opt[n] = best_of(opt[n - 1], opt[n ...

qq_33268394的博客 869

51nod 1674 区间的价值 V2(分治)

题解连接:http://blog.youkuaiyun.com/lxy767087094/article/details/77623448 倒是能想得起来分治做,但是不会分治。题解中讲得挺好。膜。。#include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 100100; const int mod

梦幻的蔷薇色 364

[分治] 51Nod1555 布丁怪

注意到这种问题可以转化到序列上,等价于:求满足出现的数字连续的区间数。和 51nod1810 连续区间 一模一样。 水 blogblog~这里写代码片

Lynstery's blog 416

SPOJ:House Fence(分治&DP)

题目链接:https://vjudge.net/problem/SPOJ-NPC2014B题意:有N个宽度为1的相邻围栏,每个有高度a[i],现在有一把宽度为1的刷子,可以横着刷或者竖着刷,问最少多少次刷完题解:对于每个区间,我们的最优情况的全部竖着刷, 或者横着刷全部公有的部分,其他的继续讨论。由于每次最小横着刷一个,所以讨论次数不超过N。复杂度低于O(N^2)代码:#include &lt;b...

qq_36876305的博客 380

51nod 1810 连续区间(分治)

原博文地址:http://blog.youkuaiyun.com/alan_cty/article/details/74905573 Description给出一个1~n的排列,求有多少个区间将区间内所有元素排序后,任意相邻两个元素值差为1 n<=1e6Solution个人认为马拉松26中最可做的一道题(然而还是没有做出来 考虑分治,也就是我们要统计左端点在[l,mid],右端点在[mid+1,r]的

huatian5的博客 824
上一篇: [最短路图][DP] ARC090 E - Avoiding Collision
下一篇: [分治][Trie][prufer数列] 51Nod 1601 完全图的最小生成树计数
Vectorxj
博客等级 码龄11年 35粉丝 231原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值