这题Day by Day可以90分的。
把询问转成离线,扫一遍就可以。
emmm,然后可以跳月。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<cmath>
#define ll long long
using namespace std;
const int N = 1e6 + 5;
ll r[N],maxn;
ll q,tot[N],ans[N][4];
int d[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool cmp(int a,int b){
return r[a] < r[b];
}
bool is_runnian(int yr){
if(yr < 0){
int absn = abs(yr) - 1;
if(absn % 4 == 0) return true;
else return false;
}
else if(yr <= 1582){
if(yr % 4 == 0) return true;
else return false;
}
else if(yr > 1582){
if(yr % 400 == 0 ) return true;
if(yr % 4 == 0 && yr % 100 != 0) return true;
return false;
}
}
void work(){
int p = 1;
int rst = 0;
int i,j,k;
for(i = -4713; rst <= maxn + 5; i++){
if(i == 0) continue;
for(j = 1; j <= 12; j++){
int maxk = d[j];
if(j == 2 && is_runnian(i)) maxk = 29;
if(!(i == 1582 && j == 10 ) && r[tot[p]] - rst > maxk + 5) rst += maxk;
else for(int k = 1; k <= maxk; k++){
if(i == 1582 && j == 10 && k >= 5 && k <= 14) continue;
rst++;
if(rst == r[tot[p]] + 1){
ans[tot[p]][0] = i;
ans[tot[p]][1] = j;
ans[tot[p]][2] = k;
p++;
}
}
}
}
}
int main(){
cin >> q;
for(int i = 1; i <= q; i++){
scanf("%d",&r[i]);
maxn = max(maxn,r[i]);
tot[i] = i;
}
sort(tot + 1,tot + q + 1,cmp);
work();
for(int i = 1; i <= q; i++)
if(ans[i][0] < 0) printf("%d %d %d BC
",ans[i][2],ans[i][1],-ans[i][0]);
else printf("%d %d %d
",ans[i][2],ans[i][1],ans[i][0]);
return 0;
}