55pts求优化
查看原帖
55pts求优化
627307
zing_Sing楼主2023/5/2 09:09

RT,是在卡不过去了,求大佬帮卡常或验证算法正确性!

#include<bits/stdc++.h>                 
using namespace std;
const int N=2.5e5+5,mod=998244353;
int read(){
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
int getm(int x){return x>mod?x-mod:x;}
struct noi{
	int c[5][5],l,r;
	noi(){
		c[1][1]=c[1][2]=c[1][3]=c[1][4]=0;
		c[2][1]=c[2][2]=c[2][3]=c[2][4]=0;
		c[3][1]=c[3][2]=c[3][3]=c[3][4]=0;
		c[4][1]=c[4][2]=c[4][3]=c[4][4]=0;
	}
    inline void init(){
		c[1][2]=c[1][3]=c[1][4]=0;
		c[2][1]=c[2][3]=c[2][4]=0;
		c[3][1]=c[3][2]=c[3][4]=0;
		c[4][1]=c[4][2]=c[4][3]=0;
		c[1][1]=c[2][2]=c[3][3]=c[4][4]=1;
	}
	noi operator+(const noi &b)const{
		noi res;
		for(int i=1;i<=4;i++){
			res.c[i][1]=(1ll*c[i][1]+b.c[i][1])%mod;
			res.c[i][2]=(1ll*c[i][2]+b.c[i][2])%mod;
			res.c[i][3]=(1ll*c[i][3]+b.c[i][3])%mod;
			res.c[i][4]=(1ll*c[i][4]+b.c[i][4])%mod;
		}
		return res;
	}
	noi operator*(const noi &b)const{
		noi res;
		for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++){
            res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][1]*b.c[1][j])%mod);
            res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][2]*b.c[2][j])%mod);
            res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][3]*b.c[3][j])%mod);
            res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][4]*b.c[4][j])%mod);
        }
		return res;
	}
}a[N<<2],input[N],base[10];
noi sum[N<<2],lazy[N<<2],ans;
inline void pushup(int x){
	sum[x]=sum[x<<1]+sum[x<<1|1];
}
inline void build(int now,int l,int r){
	lazy[now].init();
	a[now].l=l,a[now].r=r;
	if(l==r){
		sum[now].c[1][1]=input[l].c[1][1];sum[now].c[1][2]=input[l].c[1][2];
		sum[now].c[1][3]=input[l].c[1][3];sum[now].c[1][4]=1;
		return;
	}
	int mid=l+r>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	pushup(now);
}
inline void pushdown(int x){
	sum[x<<1]=sum[x<<1]*lazy[x];
	lazy[x<<1]=lazy[x<<1]*lazy[x];
	sum[x<<1|1]=sum[x<<1|1]*lazy[x];
	lazy[x<<1|1]=lazy[x<<1|1]*lazy[x];
	lazy[x].init();
}
inline void update(int now,int l,int r,noi k){
	if(a[now].l>=l&&a[now].r<=r){
		sum[now]=sum[now]*k;
		lazy[now]=lazy[now]*k;
		return;
	}
	pushdown(now);
	int mid=a[now].l+a[now].r>>1;
	if(mid>=l)update(now<<1,l,r,k);
	if(mid<r)update(now<<1|1,l,r,k);
	pushup(now);
}
inline noi query(int now,int l,int r){
	if(a[now].l>=l&&a[now].r<=r)return sum[now];
	pushdown(now);
	int mid=a[now].l+a[now].r>>1;
	noi res;
	if(mid>=l)res=res+query(now<<1,l,r);
	if(mid<r)res=res+query(now<<1|1,l,r);
	return res;
}
int main(){
	int n(read());
	for(int i=1;i<=n;i++)
		input[i].c[1][1]=read(),input[i].c[1][2]=read(),input[i].c[1][3]=read(); 
	base[1].c[1][1]=base[1].c[2][1]=base[1].c[2][2]=base[1].c[3][3]=base[1].c[4][4]=1;
	base[2].c[1][1]=base[2].c[2][2]=base[2].c[3][2]=base[2].c[3][3]=base[2].c[4][4]=1;
	base[3].c[1][1]=base[3].c[1][3]=base[3].c[2][2]=base[3].c[3][3]=base[3].c[4][4]=1;
	base[4].c[1][1]=base[4].c[2][2]=base[4].c[3][3]=base[4].c[4][4]=1;
	base[5].c[1][1]=base[5].c[3][3]=base[5].c[4][4]=1;
	base[6].c[1][1]=base[6].c[2][2]=base[6].c[4][4]=1;
	build(1,1,n);
	int m(read());
	while(m--){
		int f(read()),l(read()),r(read());
		if(f>=4&&f<=6){
			int v=read();
			if(f==4)base[4].c[4][1]=v;
			else if(f==5)base[5].c[2][2]=v;
			else base[6].c[4][3]=v;
		}
		if(f==7){
			ans=query(1,l,r);
			printf("%d %d %d\n",ans.c[1][1],ans.c[1][2],ans.c[1][3]);
		}
		else update(1,l,r,base[f]);
	}
	return 0;
}
/*
5
0 2 3
3 2 2
2 2 0
1 1 1
2 2 1
4
3 4 5
4 3 4 0
1 1 5
7 3 5
*/ 

记录

2023/5/2 09:09
加载中...