您的位置:首页 > 其它

ZOJ 3772 Calculate the Function(线段树+矩阵)

2015-05-11 16:49 302 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235

题意:

题意很好懂 就是

给定一个数列  a1,a2,...,an 

对于一个递推式 F[L]=a[L],F[L+1]=a[L+1],F[X] = F[X-1]+F[X-2]*aX,

然后给定m个询问,每次给定L,R, 求F(R);

对于这个递推式 每一项我们可以得到一个状态转移矩阵 

| F[x]    |   | 1   ,    a[x] |

|           |= |                  |

| F[x-1] |   | 1   ,      0   |

所以我们可以用线段树维护这个矩阵,值得因为矩阵的乘法满足结合律不满足交换律

因此我们在维护的时候需要注意一下 F[R] = (Mr*Mr-1*.....*Ml+2)*A;要注意维护的时候

要保证好这个顺序。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
#define lson(id) id<<1
#define rson(id) id<<1|1

using namespace std;

const LL mod = 1e9+7;
const int maxn = 1e5+10;

int a[maxn];

struct matrix{
LL m[2][2];
matrix(){CLR(m);}
matrix operator *(const struct matrix &tmp){
matrix ans;
REP(i,2){
REP(j,2){
ans.m[i][j]=0;
REP(k,2)
ans.m[i][j]=(ans.m[i][j]+m[i][k]*tmp.m[k][j])%mod;
}
}
return ans;
}
};

struct seg_tree{
int l,r;
matrix ans;
}t[maxn<<2];

void build(int id,int l,int r){
t[id].l=l,t[id].r=r;
if(l==r){
t[id].ans.m[0][0]=1;
t[id].ans.m[0][1]=a[l];
t[id].ans.m[1][0]=1;
t[id].ans.m[1][1]=0;
//cout<<"*** "<<t[id].ans.m[0][1]<<endl;
return;
}
int mid=(l+r)>>1;
build(lson(id),l,mid);
build(rson(id),mid+1,r);
t[id].ans=t[rson(id)].ans*t[lson(id)].ans;
}
matrix query(int id,int l,int r){
if(l==t[id].l&&r==t[id].r) return t[id].ans;
int mid = (t[id].l+t[id].r)>>1;
if(mid>=r) return query(lson(id),l,r);
else if(mid<l) return query(rson(id),l,r);
else return query(rson(id),mid+1,r)*query(lson(id),l,mid);
}

int main()
{
int t,n,m,l,r;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
FOR(i,1,n) scanf("%d",&a[i]);
build(1,1,n);
REP(i,m){
scanf("%d%d",&l,&r);
if(r-l>=2){
matrix tmp;
tmp.m[0][0]=a[l+1];
tmp.m[1][0]=a[l];
matrix ans =query(1,l+2,r)*tmp;
printf("%lld\n",ans.m[0][0]);
}
else
printf("%d\n",a[r]);
}
}
return 0;
}


 

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