首页 > 其他 > 详细

ZOJ3772_Calculate the Function

时间:2014-07-29 10:45:36      阅读:425      评论:0      收藏:0      [点我收藏+]

给出一些数组a[i],每次询问为li,ri,定义f[li]=a[li],f[li+1]=a[li+1],对于其他不超过ri的位置,f[x]=f[x-1]+a[x]*f[x-2] 。

题目有着浓浓的矩阵气息。

f[x]=f[x-1]+a[x]*f[x-2] 

f[x-1]=f[x-1]+0

根据上面两个我们就可以知道

f[x]=========|1,a[x]|         f[x-1]

f[x-1]=======|1 ,  0|         f[x-2]

这样我们就把矩阵构造出来了,相当于每次询问某一段区间的矩阵的乘积。

由于是连续的区间,线段树即可解决问题。

注意矩阵是放在左边,所以大的位置放在左边,线段树操作的时候也需要注意了。

 

 

召唤代码君:

 

 

#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 300300
#define mod 1000000007
typedef long long ll;
using namespace std;

class Mat{
public:
    ll f[2][2];
    Mat() { f[0][0]=f[1][1]=f[0][1]=f[1][0]=0; }
    Mat(int f1,int f2,int f3,int f4){
        f[0][0]=f1,f[0][1]=f2,f[1][0]=f3,f[1][1]=f4;
    }
    Mat operator * (Mat m1) const{
        Mat m0;
        for (int i=0; i<2; i++)
            for (int j=0; j<2; j++)
                for (int k=0; k<2; k++)
                    m0.f[i][j]=(m0.f[i][j]+f[i][k]*m1.f[k][j])%mod;
        return m0;
    }
    void output(){
        cout<<f[0][0]<< <<f[0][1]<<\n<<f[1][0]<< <<f[1][1]<<\n;
    }
}tree[maxn];

int n,m,T,a[maxn];

void build(int rt,int l,int r)
{
    if (l==r){
        tree[rt]=Mat(1,a[l],1,0);
        return;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    tree[rt]=tree[rt<<1|1]*tree[rt<<1];
}

Mat query(int rt,int l,int r,int L,int R)
{
    if (L<=l && R>=r) return tree[rt];
    int mid=(l+r)>>1;
    Mat tot(1,0,0,1);
    if (R> mid) tot=query(rt<<1|1,mid+1,r,L,R);
    if (L<=mid) tot=tot*query(rt<<1,l,mid,L,R);
    return tot;
}

int main()
{
    int x,y;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n; i++) scanf("%d",&a[i]);
        build(1,1,n);
        while (m--)
        {
            scanf("%d%d",&x,&y);
            if (y==x || y==x+1){
                if (y==x) printf("%d\n",a[x]);
                    else printf("%d\n",a[x+1]);
                continue;
            }
            Mat tmp=query(1,1,n,x+2,y);
            /*
            cout<<" ans Mat is : \n";
            tmp.output();
            cout<<" ...........   the end of Mat.";
            */
            printf("%d\n",(int)((tmp.f[0][0]*a[x+1]+tmp.f[0][1]*a[x])%mod));
        }
    }
    return 0;
}

 

ZOJ3772_Calculate the Function,布布扣,bubuko.com

ZOJ3772_Calculate the Function

原文:http://www.cnblogs.com/Canon-CSU/p/3873730.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!