第 45 届国际大学生程序设计竞赛(ICPC)亚洲网上区域赛模拟赛

A. Easy Equation : https://ac.nowcoder.com/acm/contest/8688/A

如果固定一个 \(x\), 那么 \(x + y\) 的所有可能取值即为 \([x, x + b]\), 也即 \(x\)\([x, x + b]\) 的贡献为 \(1\)
如果固定了 \(x + y\), 同理 \(x + y + z\) 的所有可能取值即为 \([x + y, x + y + c]\), 设 \(f[i]\) 表示 $ x + y = i $的方案数,
也即 \(x + y\)\([x + y, x + y + c]\) 的贡献为 $ f[x + y] $, 设 \(g[i]\) 表示 $ x + y + z = i$ 的方案数

贡献即为区间加,可以利用差分数组转化成单点修改,而最终的答案即为 \(sum_{i = 0}^{d}{g[i]}\)

注意数组下标越界

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;

const int maxn = 3000010;

int a, b, c, d;
ll f[maxn], g[maxn], ans;

ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }

int main(){
	a = read(), b = read(), c = read(), d = read();
	
	for(int i = 0 ; i <= a ; ++i){
		f[i] += 1;
		f[i + b + 1] -= 1;
	}
	for(int i = 1 ; i <= a + b ; ++i) f[i] = f[i - 1] + f[i];
	
	for(int i = 0 ; i <= a + b ; ++i){
		g[i] += f[i];
		g[i + c + 1] -= f[i];
	}
	
	ll ans = g[0];
	for(int i = 1 ; i <= d ; ++i){
		g[i] = g[i - 1] + g[i];
		ans += g[i];
	} 
	
	printf("%lld\n", ans);
	
	return 0;
}
posted @ 2020-11-19 00:14  Tartarus_li  阅读(337)  评论(0编辑  收藏  举报