zoukankan      html  css  js  c++  java
  • 第 45 届国际大学生程序设计竞赛(ICPC)亚洲网上区域赛模拟赛 A.Easy Equation(差分数组)(a+b+c=d的种数)

    地址:https://ac.nowcoder.com/acm/contest/8688/A

    题意:

    给出x,y,z,k的范围a,b,c,d
    求能组成多少种x+y+z=k

    解析:

    这是差分数组推导过程的入口:https://www.cnblogs.com/liyexin/p/11014218.html

    考虑先枚举a,得出所有的0~a+b的每个结果的数目。

    然后在得知a+b的每个数目的情况下,再得到所有0~a+b+c的每个结果的数目。

    实现过程,可以通过差分数组来实现。

    先枚举a,那么对于每个a,a+b的范围在a~a+b之间,那么范围内每个结果的数目都要+1,有:f[i]++,f[i+b+1]--

    前缀和操作一下,还原数组。

    同理,在f[]已知各个a+b的种类情况下,枚举a+b,通过f[]来求0~a+b+c的每个出现次数

    前缀和还原。

    接下来把p[]加到d即可。

    #include<iostream>
    #include<cmath>
    using namespace std;
    #include<map>
    typedef long long ll;
    const int maxn=1e8;
    ll f[maxn],p[maxn];
    int main()
    {
        ll a,b,c,d;
        cin>>a>>b>>c>>d;
        for(int i=0;i<=a;i++)
        {
            f[i]++;
            f[i+b+1]--;
        }
        for(int i=0;i<=a+b;i++)
            f[i]+=f[i-1];
        for(int i=0;i<=a+b;i++)
        {
            p[i]+=f[i];
            p[i+c+1]-=f[i];
        }
        for(int i=0;i<=a+b+c;i++)
            p[i]+=p[i-1];
        ll all=0;
        for(int i=0;i<=d;i++)
        {
            all+=p[i];
        }
        cout<<all<<endl;
        return 0;
    }

    记在后面:

    比赛前期过程中,队伍陷入了一个误区,总是在思考怎么去掉a+b+c!=d的方法。其实反向思考一下,把所有种类弄出来,想办法记录。取a+b+c==d不就可以了吗?

  • 相关阅读:
    Linux初始root密码设置
    ubuntu上的附件-终端和用快捷键ctrl+alt+f1 有啥区别
    分区工具PQ
    饮品DIY
    烘焙学习
    育儿所悟、所感、所想
    Linux netstat命令详解
    sharepoint环境安装
    python os模块
    java泛型
  • 原文地址:https://www.cnblogs.com/liyexin/p/13909430.html
Copyright © 2011-2022 走看看