zoukankan      html  css  js  c++  java
  • 【百度之星2014~初赛(第二轮)解题报告】JZP Set

    声明

       笔者近期意外的发现 笔者的个人站点 http://tiankonguse.com/ 的非常多文章被其他站点转载,可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站点,因此,笔者加入此条声明。

        郑重声明:这篇记录《【百度之星2014~初赛(第二轮)解题报告】JZP Set》转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=668


    前言

    近期要毕业了,有半年没做比赛了.
    这次參加百度之星第二轮娱乐一下.
    如今写一下 JZP Set 这道题的的解题报告.

    正文


    题意


    题意是:给你n个数(1到n),给你一个规则。问用这个规则能够得到多少个合法的集合.

    详细规则是:一个合法集合里随意挑两个数,假设这两个数之和是偶数,这个偶数除以2得到的数也要在这个合法集合里.

    比方: 3 和9 在集合里,3+9是偶数。所以 (3+9)/2 = 6 也要在这个集合里.然后 {3,6,9}就是一个合法的集合.


    起初我理解错题意了,以为是随意的两个数字之和除以2.比方 (3 + 6)/2 = 4, 我以为4也要在集合里.

    于是非常快得到一个 (n+1)*n/2 的公式.

    后来学弟告诉我正确的题意.


    分析


    这个题的例子有10^5个,每一个例子最大是10^7.



    错误题意


    首先来看看我理解错误题意时,是怎么做的.

    如果 F(n) 是 n 的答案的话, 则 F(n + 1) = F(n) + f(n+1).

    f(n+1)里面肯定有 n+1, 我如果f(n+1) 这些集合的任一个集合 S 里的最小值是 a, 则 (a+n+1)/2 肯定在 S 里面。然后这样递归下去发现 a到n+1的全部数字都必须在 S 里面.

    于是 f(n+1) 就是  n+ 1 了.

    于是终于方程就是  F(n+1) = F(n) + n+ 1.


    仅仅可惜这是错误的题意的做法.


    正确题意


    学弟告诉我正确的题意,还是能够非常快写出方程来


    F(n+1) = F(n) + f(n + 1).


    当中f(n+1) 是含有 n+ 1的合法的集合.


    奇数偶数合法<


    首先对于我上面找到的那些肯定是合法集合的一部分,仅仅是我遗漏了一些合法集合.

    遗漏的肯定是非连续的了.

    然后非常快能够想到 一个奇数和一个偶数构成的集合都是合法集合.

    于是 f(n + 1) 就又加上含有一奇一偶的合法集合的数量了,仅仅是提交后WA了.


    等差为奇数的组合


    然后学弟随手写了一个集合 {3, 6, 9 } 发现也是合法集合.

    然后我无意见把12加入进去后发现还是合法集合.

    于是我们得出结论:等差为奇数的数列都是合法集合,对于连续的那个仅仅只是是等差为1罢了.

    于是我们如果 i/x 的个数为 num(i/x),

    于是有


    则终于答案是 


    C( num (n / 1) , 2) + C( num (n / 3) , 2) + C( num (n / 5) , 2) + ...

    也就是等差位 x 的数列里。我们随便挑一段都是合法集合.

    仅仅是到这一步我们发现这样做还是超时.


    递推的等差数列


    因为F(n+1) 与 F(n) 有非常大的关系,所以我们尝试找找递推行不行.

    还是这个公式


    F(n) = F(n-1) + f(n).
    f(n) 代表含有 n 的合法集合.


    然后这些集合须要全是等差数列.

    于是写了这么一个公式

    f(n-1) =

    n/1 + n/3 + n/5 + ....



    然后就没什么想法了.


    今天看了这个解题报告才知道能够这样做.

    发现我们假设写出 f(n-2) 那一项的公式


    (n-1)/1 + (n-1)/3 + (n-1)/5 + ...
    这两个公式大部分项是相等的,仅仅有个别的几个不相等.


    自己举了几个样例发现 n 整除 以下的项时,这个除式会多一个.


    比方 n = 12
    则 12/3 = 4, 11/3 = 3.
    这样这个f(n)函数就能够转化为



    f( n ) = f( n - 1) + Count( n -1 ).
    当中 Count( n  ) 代表 n 的奇数约数个数.


    然后小舟学长的模板上刚好有求关于小于 n 的全部数的约数的个数.当中有 O( n*log(n) ) 的模板,也有 O( n ) 的模板。

    因为 n*log(n) 的模板比較简单,也能够过这道题,于是我就是用 n*log(n) 的模板了.


    代码


    /*************************************************************************
      > File Name: 4.2.cpp
      > Author: tiankonguse
      > Mail: i@tiankonguse.com
      > Created Time: Mon 26 May 2014 01:06:18 PM CST
    ***********************************************************************/
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<queue>
    #include<map>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    #include<functional>
    #include<stdarg.h>
    using namespace std;
    #ifdef __int64
    typedef __int64 LL;
    #else
    typedef long long LL;
    #endif
    const int N = 10000010;
    LL nod[N];
    LL count[N];
    LL ans[N];
    
    void __sieve_nod() {
    	memset(nod, 0,sizeof(nod));
        for (int i = 1; i < N; i+=2) {
            for (int j = i; j < N; j += i) {
                ++nod[j];
            }
        }
    }
    
    void init(){
    	ans[0] = 1;
    	ans[1] = 2;
    	LL count = 1;
    	for(int i=2;i<N;i++){
    		count += nod[i-1];
    		ans[i] = ans[i-1] + count;
    	}
    }
    
    
    int main() {
    	__sieve_nod();
    	init();
        int t,n;
        scanf("%d",&t);
        for(int i=1; i<=t; i++) {
            scanf("%d",&n);
            printf("Case #%d:
    %I64d
    ",i,ans[n]);
        }
        return 0;
    }
    



    參考

    http://acm.hdu.edu.cn/showproblem.php?

    pid=4834

    http://www.cnblogs.com/oyking/p/3751608.html

  • 相关阅读:
    226. Invert Binary Tree
    404. Sum of Left Leaves
    112. Path Sum (判断路径和是否等于某值)
    5 用两个栈实现队列
    111. Minimum Depth of Binary Tree
    110. Balanced Binary Tree
    4 重建二叉树
    108. Convert Sorted Array to Binary Search Tree
    235. Lowest Common Ancestor of a Binary Search Tree(LCA最低公共祖先)
    3 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7266563.html
Copyright © 2011-2022 走看看