• ZOJ3772_Calculate the Function


    给出一些数组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]<<'
    '<<f[1][0]<<' '<<f[1][1]<<'
    ';
        }
    }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
    ",a[x]);
                        else printf("%d
    ",a[x+1]);
                    continue;
                }
                Mat tmp=query(1,1,n,x+2,y);
                /*
                cout<<" ans Mat is : 
    ";
                tmp.output();
                cout<<" ...........   the end of Mat.";
                */
                printf("%d
    ",(int)((tmp.f[0][0]*a[x+1]+tmp.f[0][1]*a[x])%mod));
            }
        }
        return 0;
    }
  • 相关阅读:
    并发解决方案
    主外键
    ms
    mq消息丢失
    五种IO模型
    程序运行时间计算gettimeofday&clock_gettime
    exec与xargs区别
    mysql修改数据存放路径(linux)
    od用不同的编码输出文件内容
    segfault at f0 ip 00007f9954108feb sp 00007fffb5e64fc0 error 4 in libxxx.so[7f99540df000+54000]
  • 原文地址:https://www.cnblogs.com/lochan/p/3873730.html
Copyright © 2020-2023  润新知