您的位置:首页 > 其它

zoj 3772 Calculate the Function

2014-08-07 10:44 441 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235

这道题需要构造矩阵:F(X)=F(X-1)+F(X-2)*A(X)转化为F(X)*A(X+2)+F(X+1)=F(X+2),然后在构造矩阵

{1, A[x]} {F(x+1)} {F(X+2)}

{1, 0 }*{F(X) }={F(X+1)}

然后用线段数维护乘号左边的乘积;

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 101000
using namespace std;
const int mod=1000000007;

int t,a[maxn*10],n,m;
int l,r;
struct matrix
{
long long a[4][4];
};

struct node
{
int l;
int r;
matrix c;
} tree[maxn*4];

matrix multi(matrix x,matrix y)
{
matrix temp;
for(int i=1; i<=2; i++)
{
for(int j=1; j<=2; j++)
{
temp.a[i][j]=0;
for(int k=1; k<=2; k++)
{
temp.a[i][j]=(x.a[i][k]*y.a[k][j]+temp.a[i][j])%mod;
}
}
}
return temp;
}

matrix build(int i,int l,int r)
{
tree[i].l=l;
tree[i].r=r;
if(l==r)
{
tree[i].c.a[1][1]=1;
tree[i].c.a[1][2]=a[l];
tree[i].c.a[2][1]=1;
tree[i].c.a[2][2]=0;
return tree[i].c;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].c=multi(tree[i<<1|1].c,tree[i<<1].c);
return tree[i].c;
}

matrix search1(int i,int l,int r)
{
if(tree[i].l==l&&tree[i].r==r)
{
return tree[i].c;
}
int mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid)
{
return search1(i<<1,l,r);
}
else if(l>mid)
{
return search1(i<<1|1,l,r);
}
else
{
return multi(search1(i<<1|1,mid+1,r),search1(i<<1,l,mid));
}
}
int main()
{
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",&l,&r);
if(r-l>=2)
{
matrix tm,ans;
tm.a[1][1]=a[l+1];
tm.a[2][1]=a[l];
ans=multi(search1(1,l+2,r),tm);
printf("%lld\n",ans.a[1][1]);
}
else printf("%d\n",a[r]%mod);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: