HDU 5694 BD String反復
1854 ワード
BD String
テーマ接続:
http://acm.hdu.edu.cn/showproblem.php?pid=5694
Description
Problem Descriptionで知られていますが、ジグマの好きなキャラクターは二つしかありません.BとDです.
今日、BとDで文字列を構成する規則が発明されました.
S(1)=B
S(2)=BBD
S(3)=BBDBBDD
…
S(n)=S(n−1)+B+reverse(flip(S(n−1)
なお、reverse(s)は文字列を反転させることを指し、例えばreverse(BBD)=DBB、flip(s)は文字列のBをDに置換し、Dはflip(BBD)=DDBに置換する.
熊は普段はパソコンだけで遊んでいますが、これはこのマシンの比類のない演算速度を妨げていません.現在はS(21000)の内容を計算しましたが、度熊は熊だけなので、一度にこんなに長い文字列は読めません.この文字列のL番目(1からR番目)から、Bの数はどれぐらいですか?
Input
最初の行は整数Tで、T(1≦T≦1000)グループのデータを表します.
各グループのデータは、2つの数LとR(1≦L≦R≦1018)を含む.
Output
各グループのデータに対して、S(21000)で表される文字列のL番目からR番目のビットのBまでの個数が出力される.
Sample Input
3 1 3 1 7 8
Sample Output
2 4 3
ベント
題意
クイズ:
ソロを知ったら(i)、iを求める前にいくつのbがあるかを表します.
答えはソロ(r)-ソロ(l-1)ですか?
これはどうやって実現しますか?繰り返していけばいいです.
S[i]=s[i-1]+1+rs[i-1]
これは反復できます.複雑さはlognです.get関数のコードを具体的に見てください.
コード
テーマ接続:
http://acm.hdu.edu.cn/showproblem.php?pid=5694
Description
Problem Descriptionで知られていますが、ジグマの好きなキャラクターは二つしかありません.BとDです.
今日、BとDで文字列を構成する規則が発明されました.
S(1)=B
S(2)=BBD
S(3)=BBDBBDD
…
S(n)=S(n−1)+B+reverse(flip(S(n−1)
なお、reverse(s)は文字列を反転させることを指し、例えばreverse(BBD)=DBB、flip(s)は文字列のBをDに置換し、Dはflip(BBD)=DDBに置換する.
熊は普段はパソコンだけで遊んでいますが、これはこのマシンの比類のない演算速度を妨げていません.現在はS(21000)の内容を計算しましたが、度熊は熊だけなので、一度にこんなに長い文字列は読めません.この文字列のL番目(1からR番目)から、Bの数はどれぐらいですか?
Input
最初の行は整数Tで、T(1≦T≦1000)グループのデータを表します.
各グループのデータは、2つの数LとR(1≦L≦R≦1018)を含む.
Output
各グループのデータに対して、S(21000)で表される文字列のL番目からR番目のビットのBまでの個数が出力される.
Sample Input
3 1 3 1 7 8
Sample Output
2 4 3
ベント
題意
クイズ:
ソロを知ったら(i)、iを求める前にいくつのbがあるかを表します.
答えはソロ(r)-ソロ(l-1)ですか?
これはどうやって実現しますか?繰り返していけばいいです.
S[i]=s[i-1]+1+rs[i-1]
これは反復できます.複雑さはlognです.get関数のコードを具体的に見てください.
コード
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 61;
long long len[maxn],B[maxn],D[maxn],sumB[maxn];
void pre()
{
len[1]=B[1]=sumB[1]=1;
for(int i=2;i<maxn;i++){
len[i]=2LL*len[i-1]+1;
B[i]=D[i-1]+1+B[i-1];
D[i]=B[i-1]+D[i-1];
}
}
long long get(long long x)
{
if(x==0)return 0;
if(x==1)return 1;
int p=lower_bound(len+1,len+61,x)-len;
if(x==len[p])return B[p];
if(x>=(len[p-1]+1)/2+1+len[p-1])
return B[p-1]+1+get(x-len[p-1]-1)-1;
return B[p-1]+1+get(x-len[p-1]-1);
}
void solve()
{
long long l,r;
scanf("%lld%lld",&l,&r);
cout<<get(r)-get(l-1)<<endl;
}
int main()
{
pre();
int t;
scanf("%d",&t);
while(t--)solve();
return 0;
}