1. 程式人生 > 實用技巧 >第 45 屆國際大學生程式設計競賽(ICPC)亞洲網上區域賽模擬賽 A.Easy Equation(差分陣列)(a+b+c=d的種數)

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