2015长春网络赛1003(hdu5439)推公式

Aggregated Counting

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


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 number  n , 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 query  n . In case the answer is greater than  1000000006 , please modulo the answer with  1000000007 .
 

Sample Input
  
  
3 3 10 100000
 

Sample Output
  
  
11 217 507231491
 


题解:

 可以令n=1+2+2+3+3+......+ i    这个序列的长度为p

那么a[n]=1*1+2*2+3*2+...... + p*i 

那么不难发现a[a[n]] = 1*1 + (2+3)*2 + (4+5)*3 + (6+7+8)*4 + ... + (pre+1 + pre+2 + ... + pre+b[p] ) * p

b[p]为p在原序列中出现的次数

pre,b[p]这些值都可以预处理算出   每次询问可以O(1)算出答案

pre 是 第p-1项的pre + b[p-1]

                比赛没时间想了哎,赛后一推就出来了,果然还是太弱- -!

#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
          #include 
         
           #include 
          
            #include 
           
             using namespace std; typedef long long ll; const int MOD = (int)1e9+7; const int INF = (int)1e9; const int MAXN = 438744; int a[MAXN+5]; int b[MAXN+5]; int sum[MAXN+5]; int dp[MAXN+5]; int pre[MAXN+5]; int sz,val; int add(int x,int y){ x+=y; if(x>=MOD)x-=MOD; return x; } int po(int x,int n){ int ans=1; int temp=x; while(n){ if(n&1)ans=(ll)ans*temp%MOD; temp=(ll)temp*temp%MOD; n>>=1; } return ans; } int main() { val=po(2,MOD-2); a[1]=1; a[2]=2; a[3]=2; int sz=3; for(int i=3;;i++){ int cnt=a[i]; while(cnt){ a[++sz]=i; cnt--; if(sz>=MAXN)break; } if(sz>=MAXN)break; } for(int i=1;i<=MAXN;i++){ sum[i]=sum[i-1]+a[i]; if(sum[i]>=INF)break; } for(int i=1;i<=MAXN;i++){ dp[i]=add(dp[i-1],(ll)( add(add(add(pre[i-1],1),pre[i-1]),a[i]) )*a[i]%MOD*i%MOD*val%MOD); pre[i]=add(pre[i-1],a[i]); } int t;scanf("%d",&t); while(t--){ int n;scanf("%d",&n); int l=1,r=MAXN; int pos; while(l<=r){ int mid=l+r>>1; if(n<=sum[mid]){ pos=mid; r=mid-1; } else l=mid+1; } int x=n-sum[pos-1]; int ans=add(dp[pos-1],(ll)( add(add(add(pre[pos-1],1),pre[pos-1]),x) )*x%MOD*pos%MOD*val%MOD); printf("%d\n",ans); } return 0; } 
            
           
          
        
       
       
      
      
     
     
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值