【 数列做差性质 】G - Pyramid ( 打表 + 逆元 )

G - Pyramid ( 打表找规律 + 逆元 )

题意:

求n行三角形中等边三角形个数,图二的三角形也算。 n<=1e9

思路:

打表找下规律,打表方法:把所有点扔坐标系里n^3爆搜即可

打出来为 1,5,15,35,70,126,210...

没感觉,作差 4, 10, 20, 35, 56, 84

还是没感觉,作差 6, 10, 15, 21, 28

发现此时的差递增1?也就是再作差4, 5, 6, 7是等差数列

也就是再作差1, 1, 1为常数

相当于函数 An 求四次导为常数!( 如果他是个连续函数的话 )

于是我们设 An = a∗n^{4} + b∗n^{3} + c∗n^{2} + d∗n + e (别忘记常数)

解出a, b, c, d, e,

记得保留分数形式,得出a=1/24 , b=6/24, c=11/24, d=6/24, e=0.

这样提出一个1/24来,An = (1/24)*( n^{4} + 6*n^{3} + 11∗n^{2} + 6∗n )

然后逆元+O(1)代公式就完事了

 

打表时注意两个两个double类型数的相等判断需要用 fabs(a-b)<0.00001

打表代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll mod = 1e9+7;

struct node {
    double x,y;
}a[10001];
int n,cnt;

double dis( int i, int j )
{
    return sqrt( (a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y) );
}

int judge( int i, int j, int k )
{
    double a = dis(i,j);
    double b = dis(i,k);
    double c = dis(j,k);
    if ( fabs(a-b)<=0.001 && fabs(b-c)<=0.001 && fabs(a-c)<=0.001 ) return 1;
    return 0;
}

int main()
{
    while (cin >> n) {
    cnt = 0;
    double posy = 0;
    double posx = 0;
    for ( int i=n; i>=0; i-- ) {
        for ( int j=0; j<=i; j++ ) {
            a[cnt].x = posx;
            a[cnt++].y = posy + 2*j;
        }
        posx += sqrt(3);
        posy += 1.0;
    }
    //for ( int i=0; i<cnt; i++ ) cout << a[i].x<<" "<<a[i].y<<endl;
    int ans = 0;
    for ( int i=0; i<cnt; i++ ) {
        for ( int j=i+1; j<cnt; j++ ) {
            for ( int k=j+1; k<cnt; k++ ) {
                if ( judge(i,j,k)==1 ) {
                    ans ++;
                }
            }
        }
    }
    cout << ans << endl;

    }
    return 0;
}

ac代码:


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll mod = 1e9+7;

int main()
{
    ll inv24 = (mod+1)/24;
    ll n,x;
    cin >> n;
    while ( n-- ) {
        scanf("%lld",&x);
        ll ans = (((((x*x)%mod)*x)%mod)*x)%mod + 6*(((x*x)%mod)*x)%mod
        +(11*(x*x%mod)%mod) + 6*x%mod;  // 注意11*x*x可能会long long, 需要先对x*x取模再乘11
        ans %= mod;
        ans = ans*inv24%mod;
        printf("%lld\n",ans);
    }

    return 0;
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值