URAL 1309 Dispute (数学+推导)

题目链接: http://acm.timus.ru/problem.aspx?space=1&num=1309

题意:f(0) = 0, f(n) = g(n, f(n-1)),  g(x,y) = ((y-1)x5 + x3 – xy + 3x + 7y) % 9973  

输入n(n<100000000),输出 f(n) 。

思路: f[n] = f[n-1] *(n^5 - n + 7 ) + n^3 - n^5+3*n.  

令k[n] = n^5 - n + 7 , t[n] = n^3 - n^5+3*n 。即 f[n] = k[n] * f[n-1] + t[n] ;

将上式展开可得  f[n] = ( t[1]*k[2]*....*k[n] ) + ( t[2]*k[3]*....*k[n] ) +...+ t[n-1]*k[n] + t[n].

p=n/mod , q=n%mod  tmp=k[0]*k[1]*...*k[mod-1]

f[n] = ( t[mod*0+1]*k[mod*0+2]*....*k[n] )  +...+ ( t[mod*1] k[mod*1+1]*...* k[n] )              (1)

       +( t[mod*1+1]*k[mod*1+2]*....*k[n] ) +...+ ( t[mod*2] k[mod*2+1]*...* k[n] )              (2)

       ..

       +( t[mod*(p-1)+1]*k[mod*(p-1)+2]*....*k[n] )  +...+ ( t[mod*p] k[mod*p+1]*...* k[n] )   (p)

       +( t[mod*p+1]*k[mod*p+2]*....*k[n] )  +...+ t[n])

在上式中可看出  式(1) = 式(2) * tmp ;

所以 f[n] = 式(p)*(1+ tmp + ...+ tmp^(p-1))  +( t[mod*p+1]*k[mod*p+2]*....*k[n] )  +...+ t[n]).

因为其余部分和式(p) 可以暴力求出。即 可以求出f[n]了。


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod=9973;
const int maxn=mod*10;
int k[mod+15],t[mod+15],a[mod+5],n;

int mul(int num,int ct)
{
    int ret=1;
    num%=mod;
    for(int i=1;i<=ct;i++)  ret=ret*num%mod;
    return ret;
}

int main()
{
    k[0]=7; t[0]=0;
    for(int i=1;i<mod+3;i++)
    {
        k[i]=((7+mul(i,5))%mod-i+mod)%mod;
        t[i]=((mul(i,3)-mul(i,5)+mod)%mod+3*i)%mod;
    }
    int tmp=k[0],sum=0;
    for(int i=mod-1;i>=1;i--)
    {
        a[i]=tmp*t[i]%mod;
        sum=(sum+a[i])%mod;
        tmp=tmp*k[i]%mod;
    }
    while(scanf("%d",&n)!=EOF)
    {
        int p=n%mod,q=n/mod;
        int now=1,ans=0;
        for(int i=p;i>=1;i--)
        {
            ans=(ans+now*t[i]%mod)%mod;
            now=now*k[i]%mod;
        }
        int tp=sum*now%mod;
        for(int i=1;i<=q;i++)
        {
            ans=(ans+tp)%mod;
            tp=tmp*tp%mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值