Calculate the Function ZOJ - 3772

点击打开链接

通过题目给的递推公式 可以的出其矩阵形式 然后就是求某一区间的矩阵乘积 线段树或者rmq都可以解

也可以只维护一个前缀积 然后求矩阵的逆

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define M 1000000007

struct node
{
    int l;
    int r;
    ll mat[2][2];
};

node tree[400010];
ll res[2][2];
ll num[100010];
int n;

void mul(ll a[][2],ll b[][2],ll c[][2])
{
    ll t[2][2];
    int i,j,k;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            t[i][j]=0;
            for(k=0;k<2;k++)
            {
                t[i][j]=(t[i][j]+(a[i][k]*b[k][j])%M)%M;
            }
        }
    }
    memcpy(c,t,sizeof(t));
    return;
}

void pushup(int cur)
{
    mul(tree[2*cur].mat,tree[2*cur+1].mat,tree[cur].mat);
    return;
}

void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    if(l==r)
    {
        tree[cur].mat[0][0]=0,tree[cur].mat[0][1]=num[l];
        tree[cur].mat[1][0]=1,tree[cur].mat[1][1]=1;
        return;
    }
    m=(l+r)/2;
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
    pushup(cur);
    return;
}

void query(int pl,int pr,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        mul(res,tree[cur].mat,res);
        return;
    }
    if(pl<=tree[2*cur].r) query(pl,pr,2*cur);
    if(pr>=tree[2*cur+1].l) query(pl,pr,2*cur+1);
    return;
}

int main()
{
    ll ans;
    int t,q,i,l,r;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&q);
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&num[i]);
        }
        build(1,n,1);
        while(q--)
        {
            scanf("%d%d",&l,&r);
            if(r-l==0)
            {
                printf("%lld\n",num[l]%M);
            }
            else if(r-l==1)
            {
                printf("%lld\n",num[r]%M);
            }
            else
            {
                res[0][0]=1,res[0][1]=0;
                res[1][0]=0,res[1][1]=1;
                query(l+2,r,1);
                ans=((num[l]*res[0][1])%M+(num[l+1]*res[1][1])%M)%M;
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/80102489
ZOJ
今日推荐