Calculate the Function

Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Submit Status
Appoint description: 
System Crawler  (2014-04-09)

Description

You are given a list of numbers A1A2 .. AN and M queries. For the i-th query:

  • The query has two parameters Li and Ri.
  • The query will define a function Fi(x) on the domain [Li, Ri] ∈ Z.
  • Fi(Li) = ALi
  • Fi(Li + 1) = A(Li + 1)
  • for all x >= Li + 2Fi(x) = Fi(x - 1) + Fi(x - 2) × Ax

You task is to calculate Fi(Ri) for each query. Because the answer can be very large, you should output the remainder of the answer divided by 1000000007.

Input

There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

The first line contains two integers NM (1 <= NM <= 100000). The second line contains N integers A1A2 .. AN (1 <= Ai <= 1000000000).

The next M lines, each line is a query with two integer parameters LiRi (1 <= Li <= Ri <= N).

Output

For each test case, output the remainder of the answer divided by 1000000007.

Sample Input

1
4 7
1 2 3 4
1 1
1 2
1 3
1 4
2 4
3 4
4 4

Sample Output

1
2
5
13
11
4
4

题目大意:给一个n的序列,若干查询(L,R)。输出F(R)的值。

函数关系:

        F(L)=A(L)

        F(L+1)=A(L+1)

        F(X)=F(X-1)+F(X-2)*A(X) (X-L>=2)

因此每段(L,R)区间               

| F(R) |   | 1 A(R)|*| 1  A(R-1)| *......* | 1  A(L+2)|*| A(L+1)|

|F(R-1)| = | 1   0 | | 1    0   |  ......  | 1    0   | | A(L)  |

每次查询(L+2,R)区间的矩阵乘积再稍微处理一下就行了(当R-L>1时)。

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; #define Mod 1000000007
typedef long long LL;
const int maxn=;
LL a[maxn]; struct node
{
LL mat[][];
void set(int x)//初始化矩阵
{
mat[][]=;
mat[][]=a[x]%Mod;
mat[][]=;
mat[][]=; }
}; struct IntervalTree
{
int left,right;
node matrix;
}f[maxn<<]; node mat_mul_mod(node A,node B)//矩阵乘法取模
{
node ret;
ret.mat[][]=(A.mat[][]*B.mat[][]%Mod+A.mat[][]*B.mat[][]%Mod)%Mod;
ret.mat[][]=(A.mat[][]*B.mat[][]%Mod+A.mat[][]*B.mat[][]%Mod)%Mod;
ret.mat[][]=(A.mat[][]*B.mat[][]%Mod+A.mat[][]*B.mat[][]%Mod)%Mod;
ret.mat[][]=(A.mat[][]*B.mat[][]%Mod+A.mat[][]*B.mat[][]%Mod)%Mod;
return ret;
} void bulid(int left,int right,int i)//建树
{
int mid;
f[i].left=left;
f[i].right=right;
if(left==right)
{
f[i].matrix.set(left);
return;
}
mid=(left+right)>>;
bulid(left,mid,i<<);
bulid(mid+,right,i<<|);
f[i].matrix=mat_mul_mod(f[i<<|].matrix,f[i<<].matrix);
return ;
} node query(int left,int right,int i)//查询
{
int mid;
if(f[i].left==left && f[i].right==right) return f[i].matrix;
mid=(f[i].left+f[i].right)>>;
if(right<=mid) return query(left,right,i<<);
else if(left>mid) return query(left,right,i<<|);
else return mat_mul_mod(query(mid+,right,i<<|),query(left,mid,i<<));
} int main()
{
int t,n,m,i,lp,rp;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(i=;i<=n;i++)
scanf("%lld",&a[i]);
bulid(,n,);
while(m--)
{
scanf("%d %d",&lp,&rp);
if(lp==rp || lp+==rp)
{
printf("%lld\n",a[rp]%Mod);
continue;
}
node temp=query(lp+,rp,);
printf("%lld\n",(temp.mat[][]*a[lp+]%Mod+temp.mat[][]*a[lp]%Mod)%Mod);
}
}
return ;
}

ZOJ 3772 Calculate the Function 线段树+矩阵的更多相关文章

  1. Z0J 3772 Calculate the Function 线段树+矩阵

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235 这种题目居然没想到,一开始往矩阵快速幂想去了,因为之前跪了太多矩阵快速幂 ...

  2. ZOJ3772 - Calculate the Function(线段树+矩阵)

    题目大意 给定一个序列A1 A2 .. AN 和M个查询 每个查询含有两个数 Li 和Ri. 查询定义了一个函数 Fi(x) 在区间 [Li, Ri] ∈ Z. Fi(Li) = ALi Fi(Li ...

  3. 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function

    Calculate the Function Problem's Link:   http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...

  4. zoj 3772 Calculate the Function

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235 这道题需要构造矩阵:F(X)=F(X-1)+F(X-2)*A(X)转化为 ...

  5. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

  6. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并

    D. Vika and Segments     Vika has an infinite sheet of squared paper. Initially all squares are whit ...

  7. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  8. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  9. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...

随机推荐

  1. Bootstrap滚动监听(Scrollspy)插件

    Bootstrap滚动监听(Scrollspy)插件,即自动更新导航插件,会根据滚动条的位置自动更新对应的导航目标

  2. 第四次作业:Windows各种基本应用的命令处理方法

    删除文件夹命令? rd (remove directory) 如何给文件夹重新命名? ren (rename) 如何在文件夹中建立文件夹? md swift\a 如何用命令查看文本文件的内容? typ ...

  3. JDBC操作数据库的详细步骤

    1.注册驱动 告知JVM使用的是哪一个数据库的驱动 2.创建连接 使用JDBC中的类,完成对MySQL数据库的连接 3. 得到执行sql语句的Statement对象 通过连接对象获取对SQL语句的执行 ...

  4. Java--equals和 == 的比较和equals()、HashCode()的重写

    一. equals和 == 的比较 1.== 运算符 ① == 如果比较的是基本数据类型,则比较的是值. ② == 如果比较的是引用数据类型,则比较的是地址值. 2.equals ①它属于java.l ...

  5. Java使用Apache的HttpClient组件发送https请求

    如果我们直接通过普通的方式对https的链接发送请求,会报一个如下的错误: javax.net.ssl.SSLHandshakeException: sun.security.validator.Va ...

  6. OwinStartupAttribute出错

    尝试加载应用时出现了以下错误.- 找不到包含 OwinStartupAttribute 的程序集.- 找不到包含 Startup 或 [AssemblyName].Startup 类的程序集.若要禁用 ...

  7. ThinkPHP5 高级查询之构建分组条件

    ThinkPHP5 高级查询之构建分组条件 一.在tp5中通过where方法如何构建分组条件, 例如:where user_id=$this->user_id and (status in (4 ...

  8. 【windows】共享文件夹设置

    控制面板\网络和 Internet\网络和共享中心\高级共享设置 在当前的域\公用\家庭网络 下文件和打印机共享开关打开 现在可以在 计算机-网络 里面看到共享的计算机啦 选中自己想要分享的文件,右键 ...

  9. Developing for nRF52810(转载)

    Table of Contents Introduction Hardware emulation of nRF52810 Limitations Software emulation of nRF5 ...

  10. P2598 [ZJOI2009]狼和羊的故事(最小割)

    P2598 [ZJOI2009]狼和羊的故事 题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么 ...