hdu2466-Shell Pyramid
先预处理一下层和行所对应的数,然后二分三个答案,注意细节
#include<cstdio> #define inf 0x3f3f3f3f const int maxn=2000100; typedef __int64 LL; using namespace std; int i; LL n,s,ans1,ans2,ans3; LL sum[maxn+10]; LL a[maxn+10]; void solve(){ int flag=0; LL lb=0,ub=maxn,mid=(lb+ub)>>1; while(ub-lb>1){ mid=(lb+ub)>>1; if(s>a[mid]) lb=mid; else if(s<a[mid]) ub=mid; else if(s==a[mid]) { flag=1; break; } } if(s<=a[mid]&&s>=a[mid-1]&&flag) ans1=mid; else if(s<=a[lb]&&s>=a[lb-1]) ans1=lb; else if(s<=a[ub]&&s>=a[ub-1]) ans1=ub; s-=(a[ans1-1]); //printf("%I64d\n",s); //printf("%I64d\n",ans1); flag=0; lb=1,ub=ans1,mid=(lb+mid)>>1; while(ub-lb>1){ mid=(lb+ub)>>1; // printf("%d %d\n",mid,sum[3]); if(s>sum[mid]) lb=mid; else if(s<sum[mid]) ub=mid; else if(s==sum[mid]){ flag=1; break; } } //printf("%I64d %I64d %I64d %I64d\n",sum[lb],sum[lb-1],s,lb); if(s<=sum[mid]&&s>=sum[mid-1]&&flag){ // printf("1 %I64d %I64d %I64d %I64d\n",sum[mid],sum[mid-1],s,mid); ans2=mid; } else if(s<=sum[lb]&&s>=sum[lb-1]){ // printf("2 %I64d %I64d %I64d %I64d\n",sum[lb],sum[lb-1],s,lb); ans2=lb; } else if(s<=sum[ub]&&s>=sum[ub-1]){ //printf("3 %I64d %I64d %I64d %I64d\n",sum[ub],sum[ub-1],s,ub); ans2=ub; } flag=0; lb=1,ub=ans2,mid=(lb+ub)>>1; //printf("%d\n",ans2); while(ub-lb>1){ mid=(lb+ub)>>1; if(s>sum[ans2-1]+mid) lb=mid; else if(s<sum[ans2-1]+mid) ub=mid; else if(s==mid+sum[ans2-1]) { flag=1; break; } } if(s==mid+sum[ans2-1]&&flag) ans3=mid; else if(s==lb+sum[ans2-1]) ans3=lb; else if(s==ub+sum[ans2-1]) ans3=ub; printf("%I64d %I64d %I64d\n",ans1,ans2,ans3); } int main() { for(int i=1;i<=maxn;i++) sum[i]=sum[i-1]+i; for(int i=1;i<=maxn;i++) a[i]=sum[i]+a[i-1]; scanf("%I64d",&n); while(n--){ scanf("%I64d",&s); solve(); } return 0; }