标签:
思路:可以用一个函数calc(x),表示从第一位到第x位中B字符的个数,则结果为calc(R)-calc(L),怎么样求calc(x)呢?
用一个数组a[1]~a[60](a[60]>10^18&a[59]<10^18)表示s(1)~s(60)的串长,若x==a[i],则sum=a[i]/2+1;若x<a[i]&x>a[i-1],则对应a[i-1]+1的字符一定为B,那么关于a[i-1]+1对称的两部分a[i-1]+2~x与a[i]-R+1~a[i-1]字符串取反后对称,所以这两部分字符转中B的个数和为R-a[i-1]-1,加上中间对称的B,个数为R-a[i-1],总的B字符个数为R-a[i-1]+calc(a[i]-R),然后递归求解calc(a[i]-R);
代码如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> using namespace std; long long a[70]; long long calc(long long x) { if(x==0) return 0; long long sum=0; for(int i=1;i<=60;i++) { if(a[i]==x) return x/2+1; if(x<a[i]) { sum+=x-a[i-1]; sum+=calc(a[i]-x); break; } } return sum; } int main() { int T; long long L,R; scanf("%d",&T); a[0]=0; for(int i=1;i<=60;i++) { a[i]=a[i-1]*2+1; } while(T--) { scanf("%I64d%I64d",&L,&R); printf("%I64d\n",calc(R)-calc(L-1)); } return 0; }
标签:
原文地址:http://www.cnblogs.com/chen9510/p/5515247.html