hdu 5439 Aggregated Counting(长春网络赛——找规律+二分)

来源:互联网 发布:北京装修多少钱 知乎 编辑:程序博客网 时间:2024/06/08 06:27

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5439

Aggregated Counting

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 665    Accepted Submission(s): 302


Problem Description
Aggregated Counting Meetup (ACM) is a regular event hosted by Intercontinental Crazily Passionate Counters (ICPC). The ICPC people recently proposed an interesting sequence at ACM2016 and encountered a problem needed to be solved.

The sequence is generated by the following scheme.
1. First, write down 1, 2 on a paper.
2. The 2nd number is 2, write down 2 2’s (including the one originally on the paper). The paper thus has 1, 2, 2 written on it.
3. The 3rd number is 2, write down 2 3’s. 1, 2, 2, 3, 3 is now shown on the paper.
4. The 4th number is 3, write down 3 4’s. 1, 2, 2, 3, 3, 4, 4, 4 is now shown on the paper.
5. The procedure continues indefinitely as you can imagine. 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, . . . .

The ICPC is widely renowned for its counting ability. At ACM2016, they came up with all sorts of intriguing problems in regard to this sequence, and here is one: Given a positive numbern, First of all, find out the position of the last n that appeared in the sequence. For instance, the position of the last 3 is 5, the position of the last 4 is 8. After obtaining the position, do the same again: Find out the position of the last (position number). For instance, the position of the last 3 is 5, and the position of the last 5 is 11. ICPC would like you to help them tackle such problems efficiently.

 

Input
The first line contains a positive integer T,T2000, indicating the number of queries to follow. Each of the following T lines contain a positive number n(n109) representing a query.
 

Output
Output the last position of the last position of each queryn. In case the answer is greater than 1000000006, please modulo the answer with 1000000007.
 

Sample Input
3310100000
 

Sample Output
11217507231491
 

Source
2015 ACM/ICPC Asia Regional Changchun Online
 

Recommend
hujie   |   We have carefully selected several similar problems for you:  5664 5663 5662 5661 5660 
 
题目大意::按下列规则生成一组序列,令f(n)为n这个数在序列中出现的最后一个位置,求f(f(n))的值。

解题思路:

令原序列为a,根据定义和序列的生成规则可以推出:

  • f(n)等于a的前n项和
  • f(n)是n这个数在a中出现的最后一个位置

f(f(n))的含义为:a的前m项和,m为n在a中最后出现的位置。所以f(f(n))的计算式可以写成:

f(f(n))=1 + (2+3)*2 + (4+5)*3 + (6+7+8)*4 + ... + (...+n)*t

大概就是上述的内容,我这里采用了几个数组来存取上述的过程,把公式整理出来。

详见代码。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 450010const int Mod=(1e9+7);long long a[N];//表示第i个的结尾数字int b[N];//表示i出现了几次long long s[N];//表示前i个和int main(){    a[1]=1;    a[2]=3;    a[3]=5;    b[1]=1;    b[2]=2;    b[3]=2;    s[1]=1;    s[2]=11;    s[3]=38;    int k=4,pre=4,kk=3;//k用来循环,pre表示的当前这一列数的下标,kk表示下标对应的数字是多少    while (a[k-1]<=1e9)    {        for (k=pre;k<pre+b[kk];k++)        {            b[k]=kk;            a[k]=a[k-1]+b[k];            s[k]=(s[k-1]+k*((a[k-1]+1+a[k])*(a[k]-a[k-1])/2))%Mod;        }        kk++;        pre=k;    }    int t;    scanf ("%d",&t);    while (t--)    {        int n;        scanf("%d",&n);        int l=1,r=k,mid;        while (l<=r)        {            mid=(r+l)/2;            if (n<=a[mid]&&n>a[mid-1])            {                break;            }            else            {                if (n>a[mid])                {                    l=mid+1;                }                else                    r=mid;            }        }        printf ("%lld\n",(s[mid-1]+mid*((a[mid-1]+1+n)*(n-a[mid-1])/2))%Mod);    }    return 0;}


0 0
原创粉丝点击