第 45 屆國際大學生程式設計競賽(ICPC)亞洲網上區域賽模擬賽 A.Easy Equation(差分陣列)(a+b+c=d的種數)
阿新 • • 發佈:2020-11-01
地址: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不就可以了嗎?