第 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不就可以了嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM