• 秘密


    Description

      为了探索邪恶魔王everlasting的强大力量,l1ll5决定一探究竟!

      l1ll5费尽千辛万苦,终于找到了everlasting的密室,现在,只要解决最后一道难题,他就能得到everlasting的强大力量!

      现在他的面前有x颗石子,他知道,everlasting的神秘力量只在其中的一颗石子中。他想到所有石子中蕴含的能量是不同的,而能量高的石子会将能量低的石子毁灭!每一轮操作中他可以将石子分成相等的几份(注意每轮中所有石子需要先分好组),每份中的石子都会与该份中其他石子进行碰撞,也就是说,如果一份中有s颗石子,就会发生s*(s-1)/2次碰撞!每份的石子碰撞后只会剩下一颗,而everlasting的能量只在其中能量最高的一颗中!也就是说,当分成t份石子得到t个石子后,它们之间还要继续进行下一轮操作,进行划分,碰撞,直到剩下一颗石子。而石子碰撞爆发的能量是很大的,所以l1ll5必须尽可能少的让石子发生碰撞!l1ll5当然顺利的找到了正确的方法,而真相远非如此…

      由于everlasting将自己的能量注入了石子,石子便有了灵力,它向l1ll5提出一个问题:如果石子个数分别是l,l+1,l+2,…,r,那么最优碰撞次数分别是多少,由于everlasting十分喜欢哈希,它把这些值放进一个数组a里,而最后everlasting的神秘力量值为

      c^0*a[l]+c^1*a[l+1]+...+c^(r-l)*a[r] 对1000000007取模的值。如果无法在0.1s内答对,l1ll5将一无所获。l1ll5当然会做啦,但是他想考考你...

    Input

    输入一行包含三个正整数c,l,r.

    Output

    输出一行一个正整数,表示everlasting的神秘力量值。

    Sample Input

    input1:
    2 3 4
    input2:
    3 15 51

    Sample Output

    output1:
    9
    output2:
    682142060

    HINT

    【样例说明】

    对于三个石子,需要碰撞三次。

    对于四个石子,可以分成两组分别碰撞,最后的两个再进行碰撞,需要三次。

    答案为3+2*3=9.

    【数据规模与约定】

    对于10%数据,r<=20。

    对于30%数据,r<=2000。

    对于50%数据,r<=100000。

    对于另20%数据,l=r。

    对于所有数据,均匀分布50%数据,c=1。

    对于100%数据,1<=c<=1000000007,2<=l<=r<=20000000。

    这题其实是一道利用欧拉筛原理进行优化的dp题

    dp[i]表示到i个石子最少碰撞几次,则dp[i*prime[j]]=dp[i]+dp[prime[j]]*i 根据数论知识当一个数是素数时其撞击次数只能是n*(n-1)/2,根据贪心思想

    当一个数被分成一个大合数组的小素数时撞击次数最少,因此利用欧拉筛进行状态转移

    代码:

     1 #include<cstdio>// By Yae Sakura 八重樱 
     2 #include<iostream>
     3 using namespace std;
     4 long long mod=1000000007;
     5 long long dp[20000005];
     6 int prime[6000005];
     7 bool notp[20000005];
     8 int main()
     9 {
    10     long long c,l,r;
    11     long long s=0;
    12     bool a=0;
    13     scanf("%lld%lld%lld",&c,&l,&r);
    14     long long ans=0,x;
    15     int tot=0;
    16     for(int i=2;i<=r;i++)
    17     {
    18         if(!notp[i])
    19         {
    20             prime[++tot]=i;
    21             x=i;
    22             dp[i]=(x*(x-1)/2)%mod;
    23         }
    24         for(int j=1;j<=tot&&i*prime[j]<=r;j++)
    25         {
    26             notp[i*prime[j]]=1;
    27             dp[i*prime[j]]=(1LL*dp[prime[j]]*i+1LL*dp[i])%mod;
    28             if(i%prime[j]==0)
    29             break;
    30         }
    31         if(a)
    32         s=(s*c)%mod;
    33         if(l==i)
    34         {
    35             a=1;
    36             s=1;
    37         }
    38         if(a)
    39         {
    40             ans+=s*dp[i];
    41             ans%=mod;
    42         }    
    43     } 
    44     printf("%lld",ans);
    45 } 
    View Code

    Over By Yae Sakura

  • 相关阅读:
    JS-instanceof 与typeof
    JS-面向对象相关
    spark job源代码物理执行图实战
    堆(heap)和栈(stack)的区别
    sql developer怎样调试Pipelined
    oracle dbms_output 在java中输出
    sed 用法笔记
    oracle 怎样建自增长字段
    python学习笔记--split与join用法
    如何开启php报错
  • 原文地址:https://www.cnblogs.com/mzh2017/p/8149950.html
Copyright © 2020-2023  润新知