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 }
Over By Yae Sakura