题解:AT_arc112_b [ARC112B] -- - B

题面

[ARC112B] -- - B

题面翻译

初始有一个数 \(B\), 然后他通过支付一定的钱来使这个数变为另外一个数,可以使用无数次的以下两个操作,

1.支付一元让这个数乘 \(-1\)

2.支付两元使这个数减 \(1\)

问在最多 \(C\) 元的情况下可以得到多少个数?

题目描述

すぬけくんは、整数 $ B $ を持って整数やさんを訪れました。 整数やさんでは、お金を払うことで、持っている整数を別の整数にしてもらうことができます。

具体的には、次の $ 2 $ 種類のサービスを好きな順で好きなだけ購入することができます。

  • $ 1 $ 円を払い、持っている整数を $ -1 $ 倍する。
  • $ 2 $ 円を払い、持っている整数から $ 1 $ を引く。

すぬけくんが $ C $ 円以内で作ることのできる整数は何通りありますか?

输入格式

入力は以下の形式で標準入力から与えられる。

$ B $ $ C $

输出格式

答えを出力せよ。

样例 #1

样例输入 #1

11 2

样例输出 #1

3

样例 #2

样例输入 #2

0 4

样例输出 #2

4

样例 #3

样例输入 #3

112 20210213

样例输出 #3

20210436

样例 #4

样例输入 #4

-211 1000000000000000000

样例输出 #4

1000000000000000422

提示

制約

  • \(-10^{18}\le\ B\ \le\ 10^{18}\)
  • \(1\le\ C\ \le\ 10^{18}\)
  • 入力はすべて整数

Sample Explanation 1

以下のように、$ -11,10,11 $ の $ 3 $ 通りの数を作ることができます。 - 何もしないとき、$ 0 $ 円を使って $ 11 $ を作ることができる - $ 11 $ を $ -1 $ 倍すると、$ 1 $ 円を使って $ -11 $ を作ることができる - $ 11 $ から $ 1 $ を引くと、$ 2 $ 円を使って $ 10 $ を作ることができる

Sample Explanation 2

以下のように、$ -2,-1,0,1 $ の $ 4 $ 通りの数を作ることができます。 - 何もしないとき、$ 0 $ 円を使って $ 0 $ を作ることができる - $ 0 $ から $ 1 $ を引くと、$ 2 $ 円を使って $ -1 $ を作ることができる - $ 0 $ から $ 1 $ を引いて $ -1 $ 倍すると、$ 3 $ 円を使って $ 1 $ を作ることができる - $ 0 $ から $ 1 $ を引いて $ 1 $ を引くと、$ 4 $ 円を使って $ -2 $ を作ることができる

题解

思路

  • 因为 \(-1 \times -1 = 1\),所以连续进行 \(2\) 次操作 1 就会变回原来的数。因此,为了让最后生成的数最多,就不能连续进行操作 1。

  • 题目说最多使用 \(C\) 元,所以这些钱可以不用完

综合以上 2 点,就不难发现最终生成的数可以分成 4 种。

  1. 不进行操作 1,只进行 \(k\) 次操作 2。

    此时得到的数的集合为

\[W=\left \{ x|x\in \mathbb{Z},B-\left \lfloor \frac{C}{2} \right \rfloor \le x\le B \right \} \]

  1. 先进行 \(1\) 次操作 1,再进行 \(k\) 次操作 2。

    此时得到的数的集合为

\[X=\left \{ x|x\in \mathbb{Z},-B-\left \lfloor \frac{C-1}{2} \right \rfloor \le x\le -B \right \} \]

  1. 先进行 \(k\) 次操作 2,再进行 \(1\) 次操作 1。

    此时得到的数的集合为

\[Y=\left \{ x|x\in \mathbb{Z},-B \le x\le -B+\left \lfloor \frac{C-1}{2} \right \rfloor \right \} \]

  1. 先进行 \(1\) 次操作 1,再进行 \(k\) 次操作 2,最后进行 \(1\) 次操作 1。

    此时得到的数的集合为

\[Z=\left \{ x|x\in \mathbb{Z}, B \le x \le B+\left \lfloor \frac{C-2}{2} \right \rfloor \right \} \]

所以,

\[ans=\left | W \cup X \cup Y \cup Z \right | = \left | \left \{ x|x\in \mathbb{Z},B-\left \lfloor \frac{C}{2} \right \rfloor \le x\le B+\left \lfloor \frac{C-2}{2} \right \rfloor \right \} \cup \left \{ x|x\in \mathbb{Z},-B-\left \lfloor \frac{C-1}{2} \right \rfloor \le x\le -B+\left \lfloor \frac{C-1}{2} \right \rfloor \right \} \right | \]

\[M=\left \{ x|x\in \mathbb{Z},B-\left \lfloor \frac{C}{2} \right \rfloor \le x\le B+\left \lfloor \frac{C-2}{2} \right \rfloor \right \} \]

\[N=\left \{ x|x\in \mathbb{Z},-B-\left \lfloor \frac{C-1}{2} \right \rfloor \le x\le -B+\left \lfloor \frac{C-1}{2} \right \rfloor \right \} \]

所以

\[ans=\left | M \right | +\left | N \right | -\left | M\cap N\right | \]

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int b, c, ans = 0;
signed main() {
	cin.tie(0), cout.tie(0);
	cin >> b >> c;
	if (b == 0) {// b = 0 时,特判
		cout << c / 2 + 1 + (c - 1) / 2;
		return 0;
	}
	int l1 = b - c / 2, r1 = b + (c - 2) / 2;
	int l2 = -b - (c - 1) / 2, r2 = -b + (c - 1) / 2;
	if (b < 0) {// b < 0 时,集合 M 与集合 N 是反的
		swap(l1, l2);
		swap(r1, r2);
	}
	cout << (r1 - l1 + 1) + (r2 - l2 + 1) - (l1 <= r2 ? (r2 - l1 + 1) : 0);
	return 0;
}
posted @ 2024-08-22 20:04  ggc114514  阅读(16)  评论(0)    收藏  举报