简单规律---BD String

HDU   5694

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替换为B,比如flip(BBD)=DDB。
虽然度度熊平常只用它的电脑玩连连看,这丝毫不妨碍这台机器无与伦比的运算速度,目前它已经算出了S(21000)的内容,但度度熊毕竟只是只熊,一次读不完这么长的字符串。它现在想知道,这个字符串的第L位(从1开始)到第R位,含有的B的个数是多少?

Input

第一行一个整数T,表示T(1≤T≤1000) 组数据。
每组数据包含两个数L和R(1≤L≤R≤1018) 。

Output

对于每组数据,输出S(21000)表示的字符串的第L位到第R位中B的个数。

Sample Input

3
1 3
1 7
4 8

Sample Output

2
4
3

Source

2016"百度之星" - 初赛(Astar Round2A)

Recommend

wange2014   |   We have carefully selected several similar problems for you:  5695 5694 5693 5692 5691

思路:可以用一个函数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;
}
时间: 2024-08-02 10:53:39

简单规律---BD String的相关文章

hdu-5694 BD String(分治)

题目链接: BD String Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) 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)指将字符

BD String

BD String Accepts: 388 Submissions: 1164 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 众所周知,度度熊喜欢的字符只有两个:B和D. 今天,它发明了一种用B和D组成字符串的规则: S(1)=BS(1)=BS(1)=B S(2)=BBDS(2)=BBDS(2)=BBD S(3)=BBDBBDDS(3)=B

hdu 1800 Flying to the Mars(简单模拟,string,字符串)

题目 又来了string的基本用法 //less than 30 digits //等级长度甚至是超过了int64,所以要用字符串来模拟,然后注意去掉前导零 //最多重复的个数就是答案 //关于string的修改增加的用法 #include <cstdio> #include<iostream> #include <cstring> #include <algorithm> #include<string> using namespace std

2016&quot;百度之星&quot; - 初赛(Astar Round2A)1005 BD String(HDU5694)——找规律、字符串对称、分治

分析:按照题目所给的意思每次处理得到的新的字符串都是具有高度对称性的,举个例子,如题目所给的第三个字符串,最中间的是B然后两边分散开去,一边是B的话另外一边关于这个中心对称的那个位置一定是D,反过来同理.那么从任意一点,只要找出他的对称中心,从对称中心的另一边到这一点他们之间的所有字符中,去除掉对称中心是B以外,其他的那些字母中,B和D的个数一定是相等的(从题目中所给的变换方法可知).那么这题就很简单了.就是关于这个对称中心找出这点到其对称点的长度len,B的个数就是len/2+1,因为len显

NOIP模拟:饼干(简单规律推导)

题目描述 小美有一张很大的网格:2 n * 2 n .每次小美会选一个小矩阵 2 x * 2 x , x > 0,小矩阵不能超过网格的边界.然后把右上一半都放上饼干.下图是当 x=1或2 的时候: 每个格子不能放 2 个饼干.问最少能空几个格子不放饼干. 输入格式 从文件 cookies.in 中读入数据.第一行一个整数 n. 输出格式 输出到文件 cookies.out 中.一行一个答案.如果答案太大了,就模 10 6 + 3. 样例输入 3 样例输出 9 数据规模 对于 100% 的数据 1

简单类型对象 String

简单值不是对象,因此也没有属性方法,因此运行下面代码时 var s1 = “some text”; var s2 = s1.substring(2); 实际上是运行在read模式,字符串的值会被直接从内存读取,会触发如下步骤 - Create an instance of the String type(new String()) - Call the specified method on the instance - Destroy the instance 因此在字符串,数字,布尔值上调用

JAVA随笔篇二(深入分析JAVA简单类型、String和对象的值传递和引用传递)

关于JAVA的值传递和引用传递,翻看了很多资料和博客,感觉大多数讲的很乱,都是自己明白了之后就不讲了的样子,终于算是比较理解这几个概念了,下面做一个总结. 1.简单类型的参数传递 Java方法的参数是简单类型的时候,是按值传递的 (pass by value).下面举一个经典的swap函数: 无法交换值的方法: package TestTransferPack; public class TestTransfer { public static void main(String[] args)

一个简单实现的string类

为了复习c++知识,简单的实现一个string类,类名为CMyString 环境说明:windows 7 64位 开发工具:Visual Studio 2015 CMyString类的头文件CMyString.h 1 #include <iostream> 2 3 #ifndef __C_MY_STRING__ 4 #define __C_MY_STRING__ 5 6 class CMyString 7 { 8 public: 9 //默认构造函数 10 CMyString(); 11 //

hdu 5694(BD String,折半递归)

1 #include <bits/stdc++.h> 2 #define lld I64d 3 using namespace std; 4 typedef long long ll; 5 vector<ll> vec; 6 /** 7 *lower_bound 返回大于或等于x 位置的指针 8 * 9 * 思路:先预处理出对称的下标放入vector 10 * dfs(x) 表示 1-x 中 B的个数 11 * (1)若x正好等于vec[i], 则 B 的个数 = vec[i-1]