求优化
查看原帖
求优化
492662
Endt楼主2022/1/26 10:17
#include<bits/stdc++.h>
using namespace std;
const int A=1,B=4;
long long mod=998244353;

void turn0(long long x[B][B]){
	for(int i=0;i<B;++i)for(int j=0;j<B;++j)x[i][j]=0;
	for(int i=0;i<B;++i)x[i][i]=1;
}

void mul(long long x[][B],long long Y[][B],long long Z[][B],const int a){//x=y*z;a:hang y
	long long y[a][B],z[B][B];
	for(int i=0;i<a;++i)for(int j=0;j<B;++j)y[i][j]=Y[i][j];
	for(int i=0;i<B;++i)for(int j=0;j<B;++j)z[i][j]=Z[i][j];
	for(int i=0;i<a;++i)for(int j=0;j<B;++j)x[i][j]=0;
	for(int i=0;i<a;++i){
		for(int j=0;j<B;++j){
			for(int k=0;k<B;++k){
				x[i][j]=(x[i][j]+(y[i][k]%mod*z[k][j]%mod)%mod)%mod;
			}
		}
	}
}
void power(long long x[B][B],long long Y[B][B],int z){//x=y^z
	if(z==0)return;
	long long y[B][B];
	for(int i=0;i<B;++i)for(int j=0;j<B;++j)y[i][j]=Y[i][j];
	turn0(x);
	if(!z)return;
	while(z>1){
		if(z&1)mul(x,x,y,B);
		mul(y,y,y,B);
		z>>=1;
	}
	mul(x,x,y,B);
}

long long a[B][B]={1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1},b[B][B]={1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1},c[B][B]={1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1},d[B][B]={1,0,0,0,0,1,0,0,0,0,1,0,/*v*/0,0,0,1},e[B][B]={1,0,0,0,0,/*v*/0,0,0,0,0,1,0,0,0,0,1},f[B][B]={1,0,0,0,0,1,0,0,0,0,0,0,0,0,/*v*/0,1};

long long t[1000005][A][B];
long long lazy[1000005][B][B];
void updata(int rt){
	if(!rt)return;
	int fa=rt>>1;
	t[fa][0][0]=(t[fa<<1][0][0]+t[fa<<1|1][0][0])%mod;
	t[fa][0][1]=(t[fa<<1][0][1]+t[fa<<1|1][0][1])%mod;
	t[fa][0][2]=(t[fa<<1][0][2]+t[fa<<1|1][0][2])%mod;
	t[fa][0][3]=(t[fa<<1][0][3]+t[fa<<1|1][0][3])%mod;
	updata(fa);
}
void bd(int l,int r,int rt){
	turn0(lazy[rt]);
	int m=l+r>>1;
	if(l==r){
		scanf("%lld%lld%lld",&t[rt][0][0],&t[rt][0][1],&t[rt][0][2]);
		t[rt][0][3]=1;
		updata(rt);
		return;
	}else{
		bd(l,m,rt<<1),bd(m+1,r,rt<<1|1);
		return;
	}
}
void downdata(int l,int r,int rt){
	int m=l+r>>1;
	long long y[B][B];
	mul(lazy[rt<<1],lazy[rt<<1],lazy[rt],B);
	mul(t[rt<<1],t[rt<<1],lazy[rt],A);
	mul(lazy[rt<<1|1],lazy[rt<<1|1],lazy[rt],B);
	mul(t[rt<<1|1],t[rt<<1|1],lazy[rt],A);
	turn0(lazy[rt]);
}

long long ans[3];
void sum(int l,int r,int rt,int L,int R){
	int m=l+r>>1;
	downdata(l,r,rt);
	if(l>=L&&m<=R){
		ans[0]+=t[rt<<1][0][0],ans[1]+=t[rt<<1][0][1],ans[2]+=t[rt<<1][0][2];
		ans[0]%=mod,ans[1]%=mod,ans[2]%=mod;
	}else if(l<=R&&m>=L){
		sum(l,m,rt<<1,L,R);
	}
	if(m+1>=L&&r<=R){
		ans[0]+=t[rt<<1|1][0][0],ans[1]+=t[rt<<1|1][0][1],ans[2]+=t[rt<<1|1][0][2];
		ans[0]%=mod,ans[1]%=mod,ans[2]%=mod;
	}else if(m+1<=R&&r>=l){
		sum(m+1,r,rt<<1|1,L,R);
	}
}
void ff(int l,int r,int rt,int L,int R,long long x[B][B]){
	int m=l+r>>1;
	downdata(l,r,rt);
	if(l>=L&&m<=R){
		mul(lazy[rt<<1],lazy[rt<<1],lazy[rt],B);
		mul(t[rt<<1],t[rt<<1],x,A);
	}else if(l<=R&&m>=L){
		ff(l,m,rt<<1,L,R,x);
	}
	if(m+1>=L&&r<=R){
		mul(lazy[rt<<1|1],lazy[rt<<1|1],lazy[rt],B);
		mul(t[rt<<1|1],t[rt<<1|1],x,A);
	}else if(m+1<=R&&r>=l){
		ff(m+1,r,rt<<1|1,L,R,x);
	}
}

int main(){
	int n,m;
	scanf("%d",&n);
	bd(1,n,1);
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		int x,l,r;
		long long v;
		scanf("%d%d%d",&x,&l,&r);
		if(x==7){
			memset(ans,0,sizeof(ans));
			sum(1,n,1,l,r);
			printf("%lld %lld %lld\n",ans[0]%mod,ans[1]%mod,ans[2]%mod);
		}
		if(x==1){
			ff(1,n,1,l,r,a);
		}
		if(x==2){
			ff(1,n,1,l,r,b);
		}
		if(x==3){
			ff(1,n,1,l,r,c);
		}
		if(x==4){
			scanf("%lld",&v);
			d[3][0]=v;
			ff(1,n,1,l,r,d);
		}
		if(x==5){
			scanf("%lld",&v);
			e[1][1]=v;
			ff(1,n,1,l,r,e);
		}
		if(x==6){
			scanf("%lld",&v);
			f[3][2]=v;
			ff(1,n,1,l,r,f);
		}
	}
	return 0;
}

感觉我写了一个矩阵慢速幂,但不知道怎么提速

p:还WA了2个点

2022/1/26 10:17
加载中...