jzoj3771-小Z的烦恼【高精度,数学】
生活随笔
收集整理的這篇文章主要介紹了
jzoj3771-小Z的烦恼【高精度,数学】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
mmm個盒子,
當第iii個盒子中放了xxx,那么i+1i+1i+1個盒子中就必須放2x2x2x(i<=mi<=mi<=m)。
求1~n1\sim n1~n,mmm個盒子,求第一個盒子中可以放多少個
解題思路
1號盒子中的肯定越小越好。
要求滿足條件那么首先x?2m?1≤nx*2^{m-1}\leq nx?2m?1≤n
那么x≤n/2m?1x\leq n/2^{m-1}x≤n/2m?1。
然后奇數是肯定可以放進去的,
然后對于每個
xxx,會封鎖x?2i(i<m)x*2^i(i<m)x?2i(i<m)。
之和我們會發現x?2mx*2^mx?2m又可以放進去了。
以此類推
我們可以發現x?2km(x%2==1,k≥0)x*2^{km}(x\%2==1,k\geq0)x?2km(x%2==1,k≥0)
所以我們考慮枚舉kkk。
開始先計算最大的xxx,統計一次奇數個數。
其實枚舉kkk,就是每次讓nnn除與2m2^m2m,然后統計一遍奇數個數。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll mod=1e11; const ll W=1000; ll a[W+10],ans[W+10],m,t,l,al; char s[W*10+10]; void print(ll x){if (x>9) print(x/10); putchar(x%10+48); return; } void init() {memset(s,0,sizeof(s));scanf("%s",s+1);scanf("%lld",&m);l=strlen(s+1);ll t=0,k=1;for(ll i=l;i>=1;i--){a[t]+=(s[i]-48)*k;k*=10;if(k==mod) t++,k=1;}l=W;al=0; } void div(ll x) {ll g=0;for(ll i=l;i>=0;i--){a[i]+=g*mod;g=a[i]%x;a[i]/=x;}while(!a[l]&&l>=0) l--; } void count_odd(){ll g=0,i;ans[0]+=a[0]%2;for(i=l;i>=0;i--){ans[i]+=(a[i]+g*mod)/2;g=a[i]%2;}ll t=max(l-1,al);if(ans[t+1]) t++;for(i=0;i<=t;i++)if(ans[i]>=mod){ans[i+1]++;ans[i]-=mod;}if(ans[i]>0) al=i;else al=i-1; } void write() {print(ans[al]);while(al--){if(ans[al]<1e10) putchar(48);if(ans[al]<1e9) putchar(48);if(ans[al]<1e8) putchar(48);if(ans[al]<1e7) putchar(48);if(ans[al]<1e6) putchar(48);if(ans[al]<1e5) putchar(48);if(ans[al]<1e4) putchar(48);if(ans[al]<1e3) putchar(48);if(ans[al]<1e2) putchar(48);print(ans[al]);}putchar('\n'); } int main() {scanf("%lld",&t);while(t--){memset(a,0,sizeof(a));memset(ans,0,sizeof(ans));init();div(1<<(m-1));count_odd();while(a[0]){div(1<<m);count_odd();}write();} }總結
以上是生活随笔為你收集整理的jzoj3771-小Z的烦恼【高精度,数学】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本地连接连不上怎么办 本地连接连不上的方
- 下一篇: 欢乐纪中某A组赛【2019.1.19】