社区讨论
求大佬给思路找错
题目总版参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lzb7ahvu
- 此快照首次捕获于
- 2024/08/01 19:36 2 年前
- 此快照最后确认于
- 2024/08/01 20:40 2 年前
CPP
/**
对于每个节点,记录1x2矩阵mat作为区间左端点的增加的斐波那契数(lazytag),第一项用于后续转移,第二项才是它加上的值
后面的依次乘上转移矩阵(如n=8,给区间1~7操作,那么lazy[1~4]=|0,1|,lazy[5-6]=|3,5|,lazy[7]=|8,13|,对于[l,r]中的点l+i,
那么l+i增加的就是lazy[l,r]*G^i(G为转移矩阵))
矩阵满足可加性,分配律,所以区间加操作只需给起点加上一个斐波那契数矩阵,后面乘转移矩阵相当于同时增加两次
预处理:
转移矩阵的1~1e5次方
转移矩阵的前缀和:
在push_down操作的时候,假设起点加上矩阵A,转移矩阵为G,单位矩阵为I:
则区间和增加AI+AG+A(G^2)+A(G^3)+...+A(G^(r-l))=A(I+G^1+G^2+G^3...+G*(r-l))
**/
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000001
using namespace std;
long long a[100100];
struct matrix2{
ll v[2][2];
matrix2 operator *(const matrix2 &b)const
{
matrix2 ret;
ret.v[0][0]=0;
ret.v[0][1]=0;
ret.v[1][0]=0;
ret.v[1][1]=0;
for(ll i=0;i<2;i++){
for(ll j=0;j<2;j++){
for(ll k=0;k<2;k++){
ret.v[i][j]+=v[i][k]*b.v[k][j];
ret.v[i][j]%=mod;
}
}
}
return ret;
}
matrix2 operator +(const matrix2 &b)const
{
matrix2 ret;
for(ll i=0;i<2;i++){
for(ll j=0;j<2;j++){
ret.v[i][j]=v[i][j]+b.v[i][j];
ret.v[i][j]%=mod;
}
}
return ret;
}
};
matrix2 gpow[100010];
matrix2 gpowq[100010];
struct matrix{
ll v[2]={0,0};
matrix operator +(const matrix &b)const
{
matrix ret;
ret.v[0]=v[0]+b.v[0];
ret.v[0]%=mod;
ret.v[1]=v[1]+b.v[1];
ret.v[1]%=mod;
return ret;
}
};
ll summa(matrix a,matrix2 b){
ll ret=0;
ret+=a.v[0]*b.v[1][0]%mod+a.v[1]*b.v[1][1]%mod;
ret%=mod;
return ret;
}
matrix summa2(matrix a,matrix2 b){
matrix ret;
for(ll j=0;j<2;j++){
for(ll k=0;k<2;k++){
ret.v[j]=a.v[k]*b.v[j][k];
ret.v[j]%=mod;
}
}
return ret;
}
struct node{
long long v,a,b;
matrix m;
}b[400000];
void create(long long p,long long l,long long r){
if(l==r){
b[p].v=a[l];
b[p].a=l;
b[p].b=r;
return;
}
else{
create(((p+1)<<1)-1,l,(l+r)/2);
create(((p+1)<<1),(l+r)/2+1,r);
b[p].v=b[((p+1)<<1)-1].v+b[((p+1)<<1)].v;
b[p].a=l;
b[p].b=r;
}
}
void push(ll p);
void mark(long long p,matrix k){
b[p].m=b[p].m+k;
b[p].v+=summa(k,gpowq[b[p].b-b[p].a]);
b[p].v%=mod;
}
void print();
void change(long long p,long long l,long long r,matrix v){
if(b[p].a>r||b[p].b<l) return;
if(b[p].a>=l&&b[p].b<=r){
mark(p,summa2(v,gpow[b[p].a-l]));
return;
}
push(p);
change(((p+1)<<1)-1,l,r,v);
change(((p+1)<<1),l,r,v);
b[p].v=b[((p+1)<<1)-1].v+b[((p+1)<<1)].v;
b[p].v+=summa(b[p].m,gpowq[b[p].b-b[p].a]);
b[p].v%=mod;
return;
}
void push(long long p){
if(b[p].m.v[0]==0&&b[p].m.v[1]==0) return;
b[((p+1)<<1)-1].v+=summa(b[p].m,gpowq[b[((p+1)<<1)-1].b-b[((p+1)<<1)-1].a]);
b[((p+1)<<1)-1].m=b[p].m+b[((p+1)<<1)-1].m;
b[((p+1)<<1)].v+=summa(summa2(b[p].m,gpow[b[(p+1)<<1].a-b[p].a]),gpowq[b[((p+1)<<1)].b-b[((p+1)<<1)].a]);
b[((p+1)<<1)].m=summa2(b[p].m,gpow[b[(p+1)<<1].a-b[p].a])+b[((p+1)<<1)].m;
b[p].m.v[0]=0;b[p].m.v[1]=0;
b[p].v=b[((p+1)<<1)-1].v+b[((p+1)<<1)].v;
b[p].v%=mod;
}
long long sum(long long p,long long l,long long r){
if(b[p].a>r||b[p].b<l) return 0;
if(b[p].a>=l&&b[p].b<=r){
return b[p].v%mod;
}
push(p);
return (sum(((p+1)<<1)-1,l,r)+
sum(((p+1)<<1),l,r))%mod;
}
int main(){
long long n,m;
cin>>n>>m;
for(long long i=0;i<n;i++){
cin>>a[i];
}
create(0,0,n-1);
gpow[0].v[0][0]=1;
gpow[0].v[0][1]=0;
gpow[0].v[1][0]=0;
gpow[0].v[1][1]=1;
gpow[1].v[0][0]=0;
gpow[1].v[0][1]=1;
gpow[1].v[1][0]=1;
gpow[1].v[1][1]=1;
for(ll i=2;i<100010;i++){
gpow[i]=gpow[i-1]*gpow[1];
}
gpowq[0].v[0][0]=1;
gpowq[0].v[0][1]=0;
gpowq[0].v[1][0]=0;
gpowq[0].v[1][1]=1;
/**
for(ll i=0;i<5;i++){
for(ll j=0;j<2;j++){
for(ll k=0;k<2;k++){
cout<<gpow[i].v[j][k]<<" ";
}
cout<<endl;
}
cout<<endl;
}
**/
for(ll i=1;i<100010;i++){
gpowq[i]=gpowq[i-1]+gpow[i];
}
matrix te;
te.v[0]=0;
te.v[1]=1;
for(ll i=0;i<m;i++){
ll t1,t2,t3;
cin>>t1>>t2>>t3;
t2--;
t3--;
if(t1==1){
change(0,t2,t3,te);
}
else{
cout<<sum(0,t2,t3)<<endl;
}
}
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...