智商药(二分查找以及动态规划)

5046. 智商药 - AcWing题库

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e9+5,M = 1e5+5,MOD=1e9+7;
int n,m;
int f[M],s[M];
struct Node {
    int l,r;
    bool operator < (const Node& b)const {
        return r<b.r;
    }
} a[M];
int getl(int u) {
    int l=0,r=m+1;
    while(l<r) {
        int mid=l+r+1>>1;
        if(a[mid].r<u) {
            l=mid;
        } else {
            r=mid-1;
        }
    }
    return l;
}
int main(void) {
    scanf("%d%d",&n,&m);
    for(int i=2; i<=m+1; i++) {
        scanf("%d%d",&a[i].l,&a[i].r);
    }
    sort(a+2,a+m+2);
    f[1]=s[1]=1;
    a[0]={-1,-1};
    LL res=0;
    for(int i=2; i<=m+1; i++) {
        //第一个右边界小于a[i].l的药的序号
        int l=getl(a[i].l);
        //第一个右边界小于a[i].r的药的序号
        int r=getl(a[i].r);
        f[i]=(s[r]-s[l]+MOD)%MOD;
        s[i]=(s[i-1]+f[i])%MOD;
        if(a[i].r==n) {
            res=(res+f[i])%MOD;
        }
    }
    printf("%lld",res);
    return 0;
}
  1. 首先,程序引入了两个库:iostreamalgorithmiostream库用于输入输出操作,algorithm库包含了一系列算法。
  2. 接着,程序使用using namespace std;,使得在程序中可以直接使用标准库中的名称,而无需添加std::前缀。
  3. 程序定义了一个长整型别名LL,以及三个常量NMMOD
  4. 定义了全局变量nm,以及两个数组fs
  5. 定义了一个结构体Node,表示一个节点,包含左边界和右边界两个属性。该结构体还定义了一个比较运算符<,用于比较两个节点的右边界。
  6. 定义了一个名为getl的函数,该函数使用二分查找算法,根据给定的右边界值,在数组a中找到第一个右边界小于给定值的节点的序号。
  7. main函数是程序的入口点。在main函数中,首先通过输入读取了两个整数nm
  8. 接着,程序通过循环读取输入,填充数组a
  9. 使用标准库函数sort对数组a进行排序。
  10. 初始化数组fs的第一个元素为1,同时设置一个虚拟节点a[0]的左右边界为-1。
  11. 定义了一个变量res用于累加结果。
  12. 通过循环遍历数组a中的每个节点。对于每个节点,通过调用getl函数找到第一个右边界小于节点左边界和右边界的节点的序号,然后利用这些序号在数组s中找到对应的值,计算得到该节点的动态规划值,并更新数组fs。如果节点的右边界等于给定的值n,则将计算得到的动态规划值累加到结果变量res中。
  13. 最后,程序输出结果变量res的值,并结束程序。

总结:该代码通过动态规划和二分查找等算法,求解某种特定问题。输入包括两个整数和两个数组,输出为一个长整型结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值