杨辉三角形//第八届北京师范大学程序设计竞赛决赛

题目链接


杨辉三角形

Time Limit: 1500ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Prev 
Submit  Status  Statistics  Discuss
  Next
Type: 
None
NoneGraph Theory     2-SAT    Articulation/Bridge/Biconnected Component     Cycles/Topological Sorting/Strongly Connected Component     Shortest Path         Bellman Ford        Dijkstra/Floyd Warshall     Euler Trail/Circuit     Heavy-Light Decomposition    Minimum Spanning Tree     Stable Marriage Problem     Trees    Directed Minimum Spanning Tree     Flow/Matching         Graph Matching            Bipartite Matching             Hopcroft–Karp Bipartite Matching             Weighted Bipartite Matching/Hungarian Algorithm         Flow             Max Flow/Min Cut            Min Cost Max Flow DFS-like     Backtracking with Pruning/Branch and Bound     Basic Recursion    IDA* Search     Parsing/Grammar    Breadth First Search/Depth First Search     Advanced Search Techniques         Binary Search/Bisection        Ternary Search Geometry     Basic Geometry    Computational Geometry     Convex Hull     Pick's TheoremGame Theory     Green Hackenbush/Colon Principle/Fusion Principle     Nim    Sprague-Grundy Number Matrix    Gaussian Elimination     Matrix ExponentiationData Structures     Basic Data Structures    Binary Indexed Tree     Binary Search Tree     Hashing    Orthogonal Range Search     Range Minimum Query/Lowest Common Ancestor     Segment Tree/Interval Tree    Trie Tree     Sorting     Disjoint SetString     Aho Corasick    Knuth-Morris-Pratt     Suffix Array/Suffix TreeMath     Basic Math    Big Integer Arithmetic     Number Theory        Chinese Remainder Theorem         Extended Euclid         Inclusion/Exclusion        Modular Arithmetic     Combinatorics         Group Theory/Burnside's lemma        Counting     Probability/Expected Value Others    Tricky     Hardest    Unusual     Brute Force    Implementation     Constructive Algorithms    Two Pointer     Bitmask    Beginner     Discrete Logarithm/Shank's Baby-step Giant-step Algorithm     Greedy    Divide and Conquer Dynamic Programming  Tag it!

  

LZM 同学比较牛, Lsy 最近也越来越生猛,他们思路快,代码速度神勇。近期惊闻此二人均要参加校赛,队里决定出些题目卡他们,因为他们的罢工给题目组留下了繁重的负担……(报复报复)
于是, XsugarX 瞄准了 LZM 不太喜欢看的数学题目以及 Lsy 猜公式的喜好,奸笑中( ^.^ )。这个数学问题是个比较古老的问题,有如下图的三角形被称为杨辉三角形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
我们记第一个 1 为第 0 行,往下依次编号。
其中三角形左右两斜边上的数字均为 1 ,其他位置均为其两肩上的数之和。
此两牛看到偶数就会觉得复杂,被卡的时间与偶数的个数成正比, XsugarX 希望能卡他们的时间越久越好。
给定任意杨辉三角的行数 n ,请输出杨辉三角中 n 中总共有多少偶数。

Input

  

一个数 n 0<=n<=3,000,000 )。表示求杨辉三角前 n 行中偶数的个数。

Output

  

一个数 R 。表示在杨辉三角前 n 行中共有 R 个偶数,由于结果可能会很大,请输出 R mod 10,000,000 的结果。

Sample Input

4

Sample Output

4

Source

第八届北京师范大学程序设计竞赛决赛

Author

XsugarX

Tags Toggle

Prev 
Submit  Status  Statistics  Discuss
  Next 

                                                                                                                                                                                                                                               
题解:杨辉三角形 分形题目,求杨辉三角形前 n 行的偶数个数。原型是基于一个定理:杨辉三角形的第 n 行中奇数个数等于 2k 个,k 为 n 表示为二进制时 1 的个数。因此,对于 n<=3000000 的数 据范围,可以线性的进行一次扫描,累和打表。 由于统计二进制位,复杂度 O(N)中的 N 会包含一小常数 C,C 为数字的长度。 大多数都是用分形来解决的,当然这也是个很自然的想法,效率会稍微低一 点。另 VIJOS 上有题目的加强版,题目数据 n<=10^50,需要根据上面的定理推倒公式, 然后快速幂+高精解决。 


附代码

方法1:

#include
#include
#define N 10000000
int a[3000001]={0};
int gs(int n)
{
    int k=0;
    while(n)
        {
            n=n&(n-1);
            k++;
        }
        return k;
}
void jg(int n)
{
    int k;
        a[2]=1;
    a[3]=0;
    for(int i=4;i<=n;i++)
    {
        a[i]=i+1-pow(2,gs(i));
      // printf("%d ",a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        a[i]=(a[i-1]+a[i])%N;
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    jg(n);
    printf("%d\n",a[n]%N);
}

方法2:

#include
 #include
 #include
 using namespace std;
 const int MOD=10000000;
 int dp[3000010];
 int sum[3000010];
 void pp()
{
    dp[0]=0;
    dp[1]=0;
    dp[2]=0;
    dp[3]=1;
    dp[4]=0;
    int x=4;
    int i;
   for( i=5;i<=3000001;i++)
    {    dp[i]=dp[i-x]*2+i-(i-x)*2;//每一行的规律
           dp[i]=dp[i]%MOD;
            if(i==x*2)
                x=x*2;
    }
    sum[0]=0;
    for(i=0;i<=3000000;i++)//加和
        sum[i]=(dp[i+1]+sum[i-1])%MOD;
}
int main()
{pp();
    int n;
    while(~scanf("%d",&n))
    {
        printf("%d\n",sum[n]);
    }
}



你可能感兴趣的:(赛后补题)