• 「AT2292」Division into Two


    传送门
    Luogu

    解题思路

    考虑如何 ( ext{DP})
    为了方便处理,我们设 (A > B)
    (dp[i]) 表示处理完 (1...i) ,并且第 (i) 个数放入关于 (A) 的集合中的方案。
    转移就只需要枚举前一个数 (j) 就好了。
    但是观察到 (N le 10^5) ,我们就需要考虑优化。
    观察到每次 (j) 的取值都是一段连续的区间,所以我们可以前缀和优化一下,就可以做到 (O(n))

    细节注意事项

    • 咕咕咕

    参考代码

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <ctime>
    #define rg register
    using namespace std;
    template < typename T > inline void read(T& s) {
     	s = 0; int f = 0; char c = getchar();
     	while (!isdigit(c)) f |= (c == '-'), c = getchar();
     	while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
     	s = f ? -s : s;
    }
    
    typedef long long LL;
    const int _ = 100010;
    const LL p = 1e9 + 7;
    
    int n; LL dp[_], sum[_], A, B, a[_];
    
    int main() {
    	read(n), read(A), read(B); if (A < B) swap(A, B);
    	for (rg int i = 1; i <= n; ++i) read(a[i]);
    	for (rg int i = 1; i + 2 <= n; ++i)
    		if (a[i + 2] - a[i] < B) return puts("0"), 0;
    	dp[0] = sum[0] = 1;
    	for (rg int l = 0, r = 0, i = 1; i <= n; ++i) {
    		while (r < i && a[i] - a[r + 1] >= A) ++r;
    		if (l <= r) dp[i] = (sum[r] - (l > 0 ? sum[l - 1] : 0ll) + p) % p;
    		sum[i] = (sum[i - 1] + dp[i]) % p;
    		if (i > 1 && a[i] - a[i - 1] < B) l = i - 1;
    	}
    	LL ans = 0;
    	for (rg int i = n; ~i; --i) {
    		ans = (ans + dp[i]) % p;
    		if (i < n && a[i + 1] - a[i] < B) break;
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    完结撒花 (qwq)

  • 相关阅读:
    MFC--响应鼠标和键盘操作
    c/C++二进制运算符
    MFC-简单的函数使用
    mfc学习之路--如何删除通过控件新增的变量
    标准BST二叉搜索树写法
    Spring4.1新特性——Spring MVC增强
    浅析JSONP-解决Ajax跨域访问问题
    关于jquery跨域请求方法
    解决jsp下载文件,迅雷下载路径不显示文件名称的问题
    REST风格URL
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/11746550.html
Copyright © 2020-2023  润新知