zoukankan      html  css  js  c++  java
  • Hdu 5407 CRB and Candies (找规律)

    题目链接:

      Hdu 5407 CRB and Candies

    题目描述:

      给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C[n][n-2],C[n][n-1],C[n][n])%(1e9+7)是多少?

    解题思路:

      刚开始的时候各种开脑洞,然后卡题卡的风生水起。最后就上了数列查询这个神奇的网站,竟然被我找到了!!!!就是把题目上给的问题转化为求lcm(1, 2, 3, 4 ...... n-2, n-1, n, n-1) / (n+1),扎扎就打了两个表一个lcm[n],区间[1,n]的最小公倍数,一个C[n],代表pow(n, mod-2),每次查询就变成了O(1)。还是依旧卡的飞起(现在想起,心还是好痛),最后发现lcm数组计算的时候由于lcm的性质限制,并不能lcm[n]=(lcm[n-1]/gcd(lcm[n-1], n)*n)%mod。随后就开始了TLE之旅,然后就在反复计算复杂度,TLE的很迷啊。怎么计算也并不会T啊,最后换了G++就通过了。(扎扎只能说是神题。恩,没错,是神题)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long LL;
     8 const int maxn = 1000005;
     9 const int mod = 1000000007;
    10 LL lcm[maxn], C[maxn], prim[maxn], cnt;
    11 bool mark[maxn];
    12 
    13 void isprim ()
    14 {
    15     cnt = 0;
    16     for (int i=2; i<maxn; i++)
    17         if (mark[i] == false)
    18         {
    19             prim[cnt++] = i;
    20             for (int j=i+i; j<maxn; j+=i)
    21                 mark[j] = true;
    22         }
    23 }
    24 LL Pow (LL x, LL n)
    25 {
    26     LL res = 1;
    27     while (n)
    28     {
    29         if (n % 2)
    30             res = (res * x) % mod;
    31         x = (x * x) % mod;
    32         n /= 2;
    33     }
    34     return res;
    35 }
    36 void init ()
    37 {
    38     for (int i=1; i<maxn; i++)
    39         C[i] = Pow(i, mod-2);
    40     isprim();
    41     for (int i=0; i<cnt; i++)
    42     {
    43         LL x = prim[i];
    44         while (x < maxn)
    45         {
    46             lcm[x] = prim[i];
    47             x *= prim[i];
    48         }
    49     }
    50     lcm[0] = 1;
    51     for (int i=1; i<maxn; i++)
    52     {
    53         if (lcm[i] == 0)
    54             lcm[i] = 1;
    55         lcm[i] = (lcm[i-1] * lcm[i]) % mod;
    56     }
    57 }
    58 int main ()
    59 {
    60     int t, n;
    61     init ();
    62     scanf ("%d", &t);
    63     while (t --)
    64     {
    65         scanf ("%d", &n);
    66         printf ("%lld
    ", lcm[n+1] * C[n+1] % mod);
    67     }
    68     return 0;
    69 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    微软与谷歌盈利模式对比分析
    unity开源移动库iTween使用完整Demo
    开发过程遇到的问题和解决方法(备忘)
    微信开发基础教程
    WorkFlow基础实战
    操作系统学习笔记
    编译原理学习
    微信生态圈盈利模式分析
    数据与计算机通信学习笔记
    利用Spring.Net技术打造可切换的分布式缓存读写类
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4747016.html
Copyright © 2011-2022 走看看