多校训练第1轮.B——Billionaire【二分 & 日期时间转换】

题目传送门


多校训练第1轮.B——Billionaire【二分 & 日期时间转换】_第1张图片


题意

  • 第一天给你0块钱,第二天给你1块钱,第三天给你块钱…
  • 初始有M块钱,初始是y年m月d日
  • 问哪天才能变成1e9富翁

题解

  • 利用转换函数二分答案即可

AC-Code

#include 
#pragma GCC optimize(2)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

const int maxn = 3e5 + 7;
const int maxm = 1e6 + 7;

int getId(int y, int m, int d) {
	if (m < 3) { y--; m += 12; }
	return 365 * y + y / 4 - y / 100 + y / 400 + (153 * (m - 3) + 2) / 5 + d - 307;
}
vector<int> date(int id) {
	int x = id + 1789995, n, i, j, y, m, d;
	n = 4 * x / 146097;
	x -= (146097 * n + 3) / 4;
	i = (4000 * (x + 1)) / 1461001; x -= 1461 * i / 4 - 31;
	j = 80 * x / 2447; d = x - 2447 * j / 80; x = j / 11;
	m = j + 2 - 12 * x; y = 100 * (n - 49) + i + x;
	return vector<int>({ y, m, d });
}

int main() {
	int T;	cin >> T;	while (T--) {
		int M, y, m, d;	cin >> M >> y >> m >> d;
		int start = getId(y, m, d);
		int l = 0, r = sqrt(2e9);
		while (l < r) {
			int mid = (l + r) >> 1;
			int v = M + (0 + mid) * (mid + 1) >> 1; // 等差数列和
			if (v >= (int)1e9)	r = mid;
			else l = mid + 1;
		}
		for (int x : date(start + l)) {
			cout << x << " ";
		}
		cout << endl;
	}
}

你可能感兴趣的:(二分,数论,2020洛谷春季ACM多校训练)