2020(ICPC)亚洲网上区域赛模拟赛 A-Easy Equation 差分 + 前缀和

2020(ICPC)亚洲网上区域赛模拟赛 A-Easy Equation 差分 + 前缀和


传送门: https://ac.nowcoder.com/acm/contest/8688/A

题意

给 出 a 、 b 、 c 、 d , x + y + z = k 的 个 数 ( 0 ≤ x ≤ a    ;    0 ≤ y ≤ b    ;    0 ≤ z ≤ c    ;    0 ≤ k ≤ d ) 给出a、b、c、d,x+y+z=k的个数(0\leq x \leq a\;;\;0\leq y \leq b\;;\;0\leq z \leq c\;;\;0\leq k \leq d) abcdx+y+z=k0xa;0yb;0zc;0kd

思路

先 考 虑 枚 举 x , 则 x + y 的 值 域 范 围 为 [ x , x + b ] 。 先考虑枚举x,则x+y的值域范围为[x, x + b]。 xx+y[x,x+b]
所 以 枚 举 x 从 0 到 a 中 , x 到 x + b 中 都 要 + 1 , 这 是 就 可 以 用 一 维 差 分 即 可 。 然 后 前 缀 和 复 原 。 所以枚举x从0到a中,x到x+b中都要+1,这是就可以用一维差分即可。然后前缀和复原。 x0axx+b+1

	for(int i = 0;i <= a; i++) {
        d1[i]++;
        d1[i + a + 1]--;
    }
    for(int i = 1;i <= a + b; i++) {
        d1[i] += d1[i - 1];
    }

同 理 , 在 考 虑 枚 举 x + y , 则 x + y + z 的 值 域 范 围 为 [ x + y , x + y + c ] 。 同理,在考虑枚举x+y,则x+y+z的值域范围为[x+y,x+y+c]。 x+yx+y+z[x+yx+y+c]
枚 举 x + y 从 0 到 a + b 中 , x + y 到 x + y + c 中 都 要 + 1 , 差 分 在 复 原 。 枚举x+y从0到a+b中,x+y到x+y+c中都要+1,差分在复原。 x+y0a+bx+yx+y+c+1

	for(int i = 0;i <= a + b; i++) {
        d2[i] += d1[i];
        d2[i + c + 1] -= d1[i];
    }

    for(int i = 1;i <= a + b + c; i++) {
        d2[i] += d2[i - 1];
    }

最 后 取 0 到 d 中 的 贡 献 即 可 。 最后取0到d中的贡献即可。 0d

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

const ll mod = 998244353;
// const ll mod = 1e9 + 7;
// const double eps = 1e-6;
const double PI = acos(-1);
// const double R = 0.57721566490153286060651209;

const int N = 1e7 + 10;
ll d1[N], d2[N];

void solve()
{
    ll a, b, c, d;
    cin >> a >> b >> c >> d;
    for(int i = 0;i <= a; i++) {
        d1[i]++;
        d1[i + a + 1]--;
    }
    for(int i = 1;i <= a + b; i++) {
        d1[i] += d1[i - 1];
    }

    for(int i = 0;i <= a + b; i++) {
        d2[i] += d1[i];
        d2[i + c + 1] -= d1[i];
    }

    for(int i = 1;i <= a + b + c; i++) {
        d2[i] += d2[i - 1];
    }

    ll ans = 0;
    for(int i = 0;i <= d; i++) {
        ans += d2[i];
    }

    cout << ans << endl;
}

signed main() {
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值