10pts二分求调
查看原帖
10pts二分求调
416242
New_hope楼主2023/10/1 11:44
#include<bits/stdc++.h>
#define N (int)4e6 + 5
using namespace std;

int date[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int s[N << 1];
const int pn = 365, rn = 366, sta = 4713, spe = 1582;

void init() {
	s[0] = pn + 1;
	for(int i = -sta + 1; i < N; i ++) {
		if(i == 0) s[i + sta] = s[i + sta - 1];
		else if(i == spe) s[i + sta] = s[i + sta - 1] + pn - 10;
		else if(i < spe) {
			if((i < 0 && (-i) % 4 == 1) || (i > 0 && i % 4 == 0)) s[i + sta] = s[i + sta - 1] + rn;
			else s[i + sta] = s[i + sta - 1] + pn;
		} else {
			if((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)) s[i + sta] = s[i + sta - 1] + rn;
			else s[i + sta] = s[i + sta - 1] + pn;
		}
	}
	return ;
}
int binary_search(int x) { // year
	int l = -sta, r = N - 1, year = 0; // 差量年
	while(l <= r) {
		int mid = (l+r) >> 1;
		if(s[mid + sta] > x) {
			r = mid - 1;
			year = mid;
		} else {
			l = mid + 1;
		}
	}
	return year;
}
int main() {

	int Q;
	scanf("%d",&Q);
	init();
	while(Q --) {

		int r;
		scanf("%d",&r); r ++;
		int y = binary_search(r);
		r -= s[sta + y - 1];
		if(y > 0) {
			if(y == spe) date[10] = 21;
			else date[10] = 31;
			if(y > spe) {
				if((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) date[2] = 29;
				else date[2] = 28;
			}
			else {
				if(y % 4 == 0) date[2] = 29;
				else date[2] = 28;
			}
		}
		else {
			if((-y) % 4 == 1) date[2] = 29;
			else date[2] = 28;
		}

		int mo = 1;
		while(date[mo] <= r) {
			r -= date[mo];
			mo ++;
		}
		if(r == 0) {
			mo --;
			r = date[mo];
		}
		if(y < 0) printf("%d %d %d BC\n",r,mo,-y);
		else printf("%d %d %d\n",r,mo,y);
	}
	return 0;
}
/*处理顺序 年 - 月 - 日
考虑二分
先统计出每一年 12.31 的儒略日 (前缀和)
二分 - 年
再拿剩余天数算
*/
2023/10/1 11:44
加载中...