jzoj3084-超级变变变【数学】
正題
題目大意
定義函數
f(x){x?1(x%2==1)x/2(x%2==0)f(x)\left\{\begin{matrix} &x-1(x\%2==1)\\ & x/2(x\%2==0) \end{matrix}\right.f(x){?x?1(x%2==1)x/2(x%2==0)?
一次變化是將x=f(x)x=f(x)x=f(x)
求A~BA\sim BA~B之間有多少個數可以變化到kkk
解題思路
其實就是f(x)=?x/2?f(x)=\lfloor x/2 \rfloorf(x)=?x/2?
計算1~B1\sim B1~B減去1~A?11\sim A-11~A?1的
然后考慮倒推,若x≤Rx\leq Rx≤R
?2nk+x2n?=k\lfloor \frac{2^nk+x}{2^n} \rfloor=k?2n2nk+x??=k
?k+x2n?=k\lfloor k+\frac{x}{2^n} \rfloor=k?k+2nx??=k
因為kkk為整數,直接調出
k+?x2n?=kk+\lfloor \frac{x}{2^n} \rfloor=kk+?2nx??=k
?x2n?=0\lfloor \frac{x}{2^n} \rfloor=0?2nx??=0
那么當x<2nx<2^nx<2n且2nk+x≤R2^nk+x\leq R2nk+x≤R
枚舉nnn,那么xxx的可取個數2n2^n2n
當kkk為偶數時,有可能是由k+1k+1k+1變來的,需要特判。
codecodecode
#include<cstdio> #define ll long long using namespace std; ll k,a,b,ans; ll get_ans(ll x) {if(k<=1) return x;ll z=1,ans=0;while(z*k<=x){ans+=z;if(z*k+z-1>x) ans-=z*k+z-1-x;z*=2;}return ans; } int main() {scanf("%lld%lld%lld",&k,&a,&b);ans+=get_ans(b)-get_ans(a-1);if(k&&!(k&1)) k++,ans+=get_ans(b)-get_ans(a-1);printf("%lld",ans); }總結
以上是生活随笔為你收集整理的jzoj3084-超级变变变【数学】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何成为一名黑客小学生如何成为一名黑客
- 下一篇: 华硕电脑数据丢失怎么办华硕电脑系统丢失怎