BD String
众所周知,度度熊喜欢的字符只有两个:B和D。
今天,它发明了一种用B和D组成字符串的规则:
S(1)=BS(1)=BS(1)=B
S(2)=BBDS(2)=BBDS(2)=BBD
S(3)=BBDBBDDS(3)=BBDBBDDS(3)=BBDBBDD
…
S(n)=S(n−1)+B+reverse(flip(S(n−1))S(n)=S(n-1)+B+reverse(flip(S(n-1))S(n)=S(n−1)+B+reverse(flip(S(n−1))
其中,reverse(s)reverse(s)reverse(s)指将字符串翻转,比如reverse(BBD)=DBBreverse(BBD)=DBBreverse(BBD)=DBB,flip(s)flip(s)flip(s)指将字符串中的BBB替换为DDD,DDD替换为BBB,比如flip(BBD)=DDBflip(BBD)=DDBflip(BBD)=DDB。
虽然度度熊平常只用它的电脑玩连连看,这丝毫不妨碍这台机器无与伦比的运算速度,目前它已经算出了S(21000)S(2^{1000})S(21000)的内容,但度度熊毕竟只是只熊,一次读不完这么长的字符串。它现在想知道,这个字符串的第LLL位(从1开始)到第RRR位,含有的BBB的个数是多少?
第一行一个整数TTT,表示T(1≤T≤1000)T(1 leq T leq 1000)T(1≤T≤1000) 组数据。
每组数据包含两个数LLL和R(1≤L≤R≤1018)R(1 leq L leq R leq 10^{18})R(1≤L≤R≤1018) 。
对于每组数据,输出S(21000)S(2^{1000})S(21000)表示的字符串的第LLL位到第RRR位中BBB的个数。
3 1 3 1 7 4 8
2 4 3
很好的解释http://www.cnblogs.com/chen9510/p/5515247.html
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdlib.h> 5 #include<string.h> 6 #include<queue> 7 #include<stack> 8 using namespace std; 9 typedef long long LL; 10 LL ans[66]; 11 LL bns[66]; 12 LL ask(LL n); 13 int main(void) 14 { 15 LL i,j,k; 16 ans[1]=1; 17 LL ak=2; 18 bns[1]=1; 19 for(i=2; i<=60; i++) 20 { 21 ak*=2; 22 ans[i]=ans[i-1]*2; 23 bns[i]=ak-1; 24 } 25 LL n,m; 26 int s; 27 cin>>s; 28 for(i=0; i<s; i++) 29 { 30 scanf("%lld %lld",&n,&m); 31 printf("%lld ",ask(m)-ask(n-1)); 32 } 33 return 0; 34 } 35 LL ask(LL n) 36 { 37 int i; 38 LL sum=0; 39 if(n==0)return 0; 40 for(i=1; i<=60; i++) 41 { 42 if(bns[i]>=n) 43 break; 44 } 45 if(n==bns[i]) 46 { 47 return ans[i]; 48 } 49 else 50 { 51 LL cc=n-bns[i-1]; 52 return cc+ask(2*bns[i-1]-n+1); 53 } 54 }