hdu 6472 艺术台阶·微积分+多项式维护

题解

懒得写了,重点直接看别人的吧

注意了,
由于题目中的h是实数范围内,所以是 ∑ i = 0 b [ 1 ] ∑ j = i b [ 2 ∑ k = j b [ 3 ] \sum^{b[1]}_{i=0}\sum^{b[2}_{j=i}\sum^{b[3]}_{k=j} i=0b[1]j=ib[2k=jb[3],而不是 ∑ i = 0 b [ 1 ] ∑ j = i + 1 b [ 2 ∑ k = j + 1 b [ 3 ] \sum^{b[1]}_{i=0}\sum^{b[2}_{j=i+1}\sum^{b[3]}_{k=j+1} i=0b[1]j=i+1b[2k=j+1b[3]

代码微积分计算部分过程原理:

在这里插入图片描述

首先,让我们模拟一遍,
假设 a n s = ∫ 0 b [ 1 ] ∫ i b [ 2 ] ∫ j b [ 3 ] 1 d k   d j   d i ans=\int^{b[1]}_0 \int^{b[2]}_i\int^{b[3]}_j 1dk\,dj\,di ans=0b[1]ib[2]jb[3]1dkdjdi 最外层是0-b[1]哦

对k层积分,
∫ j b [ 3 ] 1 d k = [ k ] j b [ 3 ] = [ c 0 + c 1 k ] j b [ 3 ] \int^{b[3]}_j 1dk=[k]^{b[3]}_{j}=[c_0+c_1k]^{b[3]}_{j} jb[3]1dk=[k]jb[3]=[c0+c1k]jb[3] 这里的cx表示的是幂次数为x的项的系数,只是作为符号,值不一定相等,这里c0=0,c1=1

得到j层的函数,
[ c 0 + c 1 k ] j b [ 3 ] = ( c 0 + c 1 b [ 3 ] ) − ( c 0 + c 1 j ) = c 1 b [ 3 ] − c 1 j = c 0 + c 1 j [c_0+c_1k]^{b[3]}_{j}=(c_0+c_1b[3])-(c_0+c_1j)=c_1b[3]-c_1j=c_0+c_1j [c0+c1k]jb[3]=(c0+c1b[3])(c0+c1j)=c1b[3]c1j=c0+c1j

然后,对j层积分
∫ i b [ 2 ] c 0 + c 1 j   d j = [ c 1 j + c 2 j 2 ] i b [ 2 ] \int^{b[2]}_{i}c_0+c_1j\,dj=[c_1j+c_2j^2]^{b[2]}_{i} ib[2]c0+c1jdj=[c1j+c2j2]ib[2]

得到i层的函数
[ c 1 j + c 2 j 2 ] i b [ 2 ] = ( c 1 b [ 2 ] + c 2 b [ 2 ] 2 ) − ( c 1 i + c 2 j 2 ) = c 0 + c 1 i + c 2 i 2 [c_1j+c_2j^2]^{b[2]}_{i}=(c_1b[2]+c_2b[2]^2)-(c_1i+c_2j^2)=c_0+c_1i+c_2i^2 [c1j+c2j2]ib[2]=(c1b[2]+c2b[2]2)(c1i+c2j2)=c0+c1i+c2i2

对i层积分得到最终答案
∫ 0 b [ 1 ] c 0 + c 1 i + c 2 i 2   d i = [ c 1 i + c 2 i 2 + c 3 i 3 ] 0 b [ 1 ] = c 1 b [ 1 ] + c 2 b [ 1 ] 2 + c 3 b [ 1 ] 3 \int^{b[1]}_0c_0+c_1i+c_2i^2\,di=[c_1i+c_2i^2+c_3i^3]^{b[1]}_{0}=c_1b[1]+c_2b[1]^2+c_3b[1]^3 0b[1]c0+c1i+c2i2di=[c1i+c2i2+c3i3]0b[1]=c1b[1]+c2b[1]2+c3b[1]3

通过以上式子观察得出,
微积分应该由内向外积分,
第i次积分,该层的 c 0 = ∑ k = 1 i − 1 c_0=\sum^{i-1}_{k=1} c0=k=1i1上一层的 c k ∗ b [ c_k*b[ ckb[本层积分的实际上限 ] k ]^k ]k,求c0是为了求出下一层的c1
而下一层的 c k c_k ck 都是由本层的 − c k − 1 ∗ 1 k -c_{k-1}*\frac{1}{k} ck1k1 转化而来(积分嘛)
最终所有计算结果统计在最外层中,

整理一下我们会用到哪些东西呢?
原上限,实际上限,各种次幂的系数,各个数的逆元


在这里插入图片描述


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int mod=1e9+7;

ll qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

int n,m,k;
ll a[N],b[N],c[N];//原上限 实际上限 指数为i次的项的系数
ll inv[N];//各个数的逆元

int main(){
    ios::sync_with_stdio(0);

    inv[1]=1;
    for (int i = 2; i <= 2005; ++i) {
        inv[i]=qpow(i,mod-2)%mod;
    }

    int T;
    cin>>T;
    for (int cs = 1; cs <= T; ++cs) {
        memset(c, 0, sizeof(c));

        cin>>n;
        ll div=1;
        for (int i = 1; i <= n; ++i) {
            cin>>a[i];
            b[i]=a[i];
            div=div*a[i]%mod;
        }
        //处理实际上限
        for (int i = n; i ; --i) {
            if(b[i-1]>b[i])
                b[i-1]=b[i];
        }

        c[1]=1;c[0]=0;
        for (int i = n,p=2; i>1; --i,p++) {//p为本层函数内的最高次项的次数
            //处理本层的c[0]
            for (int j = 0; j < p; ++j) {
                c[0]+=c[j]*qpow(b[i],j)%mod;
                c[0]%=mod;
                c[j]=-c[j];
            }
            //再处理下一层的各个系数
            for (int j = p; j; --j) {
                c[j]=c[j-1]*inv[j]%mod;
            }
            c[0]=0;//记得清0 每一层的原函数的c[0]都是0
        }

        ll ans=0;
        for (int i = 0; i <= n; ++i) {
            ans+=c[i]*qpow(b[1],i)%mod;
            ans%=mod;
        }
        ans=(ans*qpow(div,mod-2)%mod+mod)%mod;
        printf("%lld\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值