• 2020牛客暑期多校训练营(第八场)Enigmatic Partition


    题目链接

    https://ac.nowcoder.com/acm/contest/5673/E

    题目大意

    将数 x 拆分,需要满足拆分的数的最大和最小的差值为2,且相邻两个数的差值不能超过1

    定义 f(x) 为满足条件的拆分的方案数 , 求 $sum ^{R}_{i=L}fleft( i ight) $

    解题思路 

    参考博客

    打个表可以发现以 L 为最小值 , len 为长度的拆分方案数是以一定规律变化的

    (从某个数开始每隔两项满足条件的方案数+1,从某个数开始每隔两项满足条件的方案数-1)

    我们可以枚举 L 和 len , 然后每次达到某个点的时候开始更新方案数

    这个操作可以用差分去维护区间的增值和减值

    但每次更新需要从当前项不断向后移动两格直到边界 , 时间复杂度很显然是不行的

    那怎么办呢?

    当然是差分套差分啦( 也就是二阶差分 )

    用第一阶差分维护第二阶差分所要维护的区间的增值和减值就OK了

    AC_Code

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 1e5 + 10 , M = 1e6 + 10;
    int add[M] , f[N];
    void init()
    {
        int up = N - 10;
        for(int l = 1 ; l <= up ; l ++)
            for(int len = 3 ; len * l <= up ; len ++)
            {
                add[l * len + 3] ++ , add[(l + 1) * len + 1] -- ;
                add[(l + 1) * len + 2] -- , add[(l + 2) * len - 3 + 3] ++ ;
            }
        for(int i = 3 ; i <= up ; i ++) add[i] += add[i - 2];
        for(int i = 1 ; i <= up ; i ++) add[i] += add[i - 1];
        for(int i = 1 ; i <= up ; i ++) f[i] = f[i - 1] + add[i];
    }
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0) , cout.tie(0);
        init();
        int T = 1;
        cin >> T;
        for(int k = 1 ; k <= T ; k ++)
        {
            int l , r;
            cin >> l >> r;
            cout << "Case #" << k << ": ";
            cout << f[r] - f[l - 1] << '
    ';
        }
        return 0;
    }
  • 相关阅读:
    WM有约(二):配置信息
    ASP+Wrod、excel打印程序示例
    用stream直接下载文件
    ASP判断gif图像尺寸的方法
    白菜世纪RSS无刷新聚合器(1221修正)
    ASP.NET常用代码
    图片超过规定的大小就按原图片大小缩小
    javascript弹出窗口总结
    asp excel sql 关系大总结
    打开窗口
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13437401.html
Copyright © 2020-2023  润新知