• 清北学堂模拟赛d3t2 b


    分析:一道比较让人头疼的数学题.

         先考虑怎么让分出来的三角形相似,先不考虑每个三角形的具体边长,设每个三角形的周长为li,则可知必然有一个数g = gcd{li},每一个三角形的周长都是g的倍数,这样就会有n/g个单位三角形,我们只需要把n/g分配给若干个三角形就可以了,利用隔板法,可以算出方案数为2^(n/g - 1).

         再来考虑知道了周长怎么求这个周长的三角形有多少个.为了方便起见,设a ≤ b ≤ c,s = a + b + c,如果b = c,那么s = a + 2b,b的取值范围就是[g/3上取整,(g-1)/2下取整],看看取值范围内有多少个整数就有多少种方案.如果b < c,那么可以把c--,直到变成b=c,那么就是f[i] = f[i - 1],但是这样有一种特殊情况:a + b = c,这在f[i - 1]中是合法的,但是我们在处理的时候要减掉这种方案.s = 2c,c = g/2,显然只有g是偶数的时候才会出现这种情况,这时a和b只能取g/4个数,方案数减去g/4就可以了.

         但是这样还是不行,如果一个三角形边长是2,2,3,另外一个是4,4,6,那么可以将前面一个三角形作为单位三角形分配给后面的三角形,直接计算会将一个方案算多次,所以我们要求的f[s],s = a + b + c中的a,b,c必须是互质的,为了去重,每一个f[s] -= f[k],k | s.就可以了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    const int mod = 1e9 + 7;
    
    typedef long long ll;
    ll n, f[1000010], p[1000010], cnt, mi[1000010], ans;
    
    void add(ll &a, ll b)
    {
        a += b;
        if (a >= mod)
            a -= mod;
    }
    
    int main()
    {
        scanf("%lld", &n);
        for (ll i = 3; i <= n; i++)
        {
            f[i] = f[i - 1];
            add(f[i], (i - 1) / 2 - ceil((double)i * 1.0 / 3) + 1);
            if (!(i & 1))
                f[i] -= i / 4;
        }
        for (ll i = 1; i * i <= n; i++)
            if (n % i == 0)
            {
                if (i * i != n)
                {
                    p[++cnt] = i;
                    p[++cnt] = n / i;
                }
                else
                    p[++cnt] = i;
            }
        sort(p + 1, p + 1 + cnt);
        for (ll i = 1; i <= cnt; i++)
            for (ll j = 1; j < i; j++)
                if (p[i] % p[j] == 0)
                    add(f[p[i]], mod - f[p[j]]);
        mi[0] = 1;
        for (ll i = 1; i <= n; i++)
        {
            mi[i] = mi[i - 1];
            add(mi[i], mi[i - 1]);
        }
        for (ll i = 1; i <= cnt; i++)
                add(ans, mi[n / p[i] - 1] * f[p[i]] % mod);
        printf("%lld
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    php解决与处理网站高并发 大流量访问的方法
    mysql事务和锁InnoDB
    从一个死锁看mysql innodb的锁机制
    Git如何删除自己创建的项目
    公众号的坑
    字符串转Unicode码
    字符串转UTF-8码(%开头)
    git介绍和使用
    ng2中文文档地址
    两个数组的排序方法
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7650595.html
Copyright © 2020-2023  润新知