「THUSCH 2017」大魔法师

「THUSCH 2017」大魔法师

先考虑只有操作1,2,3的情况。

实际上每个数都可以用\(xA_i+yB_i+zC_i+K\)来表示。

那么对于操作4,只要\(K+=v\),操作5,只需\(x*=v,y*=v,z*=v,K*=v\),操作6,只需\(x=y=z=0,K=v\)

直接使用分块来做,十分暴力。

每个块记录\(\sum A_i ,\sum B_i ,\sum C_i\)查询和重构块的时候展开表示形式即可。

#include<bits/stdc++.h>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
#define mem(a,b) memset(a,b,sizeof a )
#define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
using namespace std;
void in(int &r) {
	static char c;
	r=0;
	while(c=getchar(),!isdigit(c));
	do r=(r<<1)+(r<<3)+(c^48);
	while(c=getchar(),isdigit(c));
}
bool cur1;
const int mn=250005;
const int mod=998244353;
int A[mn],B[mn],C[mn],n,m;
const int BLK=1600;
int blk;
struct nw{
    int a,b,c,v;
    void operator +=(const nw &A){
	    a=(a+A.a)%mod,b=(b+A.b)%mod;
	    c=(c+A.c)%mod,v=(v+A.v)%mod;
	}
	void operator *=(const int &vl){
	    a=1LL*a*vl%mod,b=1LL*b*vl%mod;
	    c=1LL*c*vl%mod,v=1LL*v*vl%mod;
	}
}an[BLK][3];
int sum[BLK][3],mxd;
static inline void ad(int &a,int b){
	mxd=a+b;
    a=mxd<mod?mxd:mxd-mod;
}
void rebuild(int id){
    int l=max(1,blk*id),r=min(n,blk*(id+1)-1);
	int mid1,mid2,mid3;
	sum[id][0]=0,sum[id][1]=0,sum[id][2]=0;
    rep(q,l,r){
	    mid1=(1LL*an[id][0].a*A[q]+1LL*an[id][0].b*B[q]+1LL*an[id][0].c*C[q]+an[id][0].v)%mod;
	    mid2=(1LL*an[id][1].a*A[q]+1LL*an[id][1].b*B[q]+1LL*an[id][1].c*C[q]+an[id][1].v)%mod;
	    mid3=(1LL*an[id][2].a*A[q]+1LL*an[id][2].b*B[q]+1LL*an[id][2].c*C[q]+an[id][2].v)%mod;
	    A[q]=mid1,B[q]=mid2,C[q]=mid3;
	    ad(sum[id][0],mid1);
	    ad(sum[id][1],mid2);
	    ad(sum[id][2],mid3);
	}
	an[id][0]={1,0,0,0};
	an[id][1]={0,1,0,0};
	an[id][2]={0,0,1,0};
}
void operator_1(int l,int r){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)ad(A[q],B[q]),ad(sum[l_id][0],B[q]);
	}else{
		rebuild(l_id),rebuild(r_id);
	    rep(q,l,(l_id+1)*blk-1)ad(A[q],B[q]),ad(sum[l_id][0],B[q]);
	    rep(q,r_id*blk,r)ad(A[q],B[q]),ad(sum[r_id][0],B[q]);
	    rep(q,l_id+1,r_id-1){
		    an[q][0]+=an[q][1];
		    ad(sum[q][0],sum[q][1]);
		}
	}
}
void operator_2(int l,int r){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)ad(B[q],C[q]),ad(sum[l_id][1],C[q]);
	}else{
		rebuild(l_id),rebuild(r_id);
	    rep(q,l,(l_id+1)*blk-1)ad(B[q],C[q]),ad(sum[l_id][1],C[q]);
	    rep(q,r_id*blk,r)ad(B[q],C[q]),ad(sum[r_id][1],C[q]);
	    rep(q,l_id+1,r_id-1){
		 	an[q][1]+=an[q][2];
		 	ad(sum[q][1],sum[q][2]);
		}
	}
}
void operator_3(int l,int r){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)ad(C[q],A[q]),ad(sum[l_id][2],A[q]);
	}else{
		rebuild(l_id),rebuild(r_id);
	    rep(q,l,(l_id+1)*blk-1)ad(C[q],A[q]),ad(sum[l_id][2],A[q]);
	    rep(q,r_id*blk,r)ad(C[q],A[q]),ad(sum[r_id][2],A[q]);
	    rep(q,l_id+1,r_id-1){
			an[q][2]+=an[q][0];
			ad(sum[q][2],sum[q][0]);
		}
	}
}
void operator_4(int l,int r,int vl){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)ad(A[q],vl);
	    sum[l_id][0]=(sum[l_id][0]+1LL*vl*(r-l+1))%mod;
	}else{
		rebuild(l_id),rebuild(r_id);
		
	    rep(q,l,(l_id+1)*blk-1)ad(A[q],vl);
	    sum[l_id][0]=(sum[l_id][0]+1LL*vl*((l_id+1)*blk-l))%mod;
	    
	    rep(q,r_id*blk,r)ad(A[q],vl);
	    sum[r_id][0]=(sum[r_id][0]+1LL*vl*(r-r_id*blk+1))%mod;
	    
	    rep(q,l_id+1,r_id-1){
	    	ad(an[q][0].v,vl);
			sum[q][0]=(sum[q][0]+1LL*vl*blk)%mod;
		}
	}
}
void operator_5(int l,int r,int vl){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)sum[l_id][1]=(sum[l_id][1]+1LL*B[q]*(vl-1)+mod)%mod,B[q]=1LL*B[q]*vl%mod;
	}else{
		rebuild(l_id),rebuild(r_id);
		
	    rep(q,l,(l_id+1)*blk-1)sum[l_id][1]=(sum[l_id][1]+1LL*B[q]*(vl-1)+mod)%mod,B[q]=1LL*B[q]*vl%mod;
	    
	    rep(q,r_id*blk,r)sum[r_id][1]=(sum[r_id][1]+1LL*B[q]*(vl-1)+mod)%mod,B[q]=1LL*B[q]*vl%mod;
	    
	    rep(q,l_id+1,r_id-1){
	    	an[q][1]*=vl;
			sum[q][1]=1LL*sum[q][1]*vl%mod;
		}
	}
}
void operator_6(int l,int r,int vl){
    int l_id=l/blk,r_id=r/blk;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)sum[l_id][2]=(1LL*sum[l_id][2]+vl-C[q]+mod)%mod,C[q]=vl;
	}else{
		rebuild(l_id),rebuild(r_id);
		
	    rep(q,l,(l_id+1)*blk-1)sum[l_id][2]=(1LL*sum[l_id][2]+vl-C[q]+mod)%mod,C[q]=vl;
	    
	    rep(q,r_id*blk,r)sum[r_id][2]=(1LL*sum[r_id][2]+vl-C[q]+mod)%mod,C[q]=vl;
	    
	    rep(q,l_id+1,r_id-1){
			an[q][2].a=0,an[q][2].b=0,an[q][2].c=0,an[q][2].v=vl;
			sum[q][2]=1LL*blk*vl%mod;
		}
	}
}
void query(int l,int r){
    int l_id=l/blk,r_id=r/blk;
    long long sm1=0,sm2=0,sm3=0;
    if(l_id==r_id){
    	rebuild(l_id);
	    rep(q,l,r)sm1+=A[q],sm2+=B[q],sm3+=C[q];
	}else{
		rebuild(l_id),rebuild(r_id);
	    rep(q,l,(l_id+1)*blk-1)sm1+=A[q],sm2+=B[q],sm3+=C[q];
	    
	    rep(q,r_id*blk,r)sm1+=A[q],sm2+=B[q],sm3+=C[q];
	    
	    rep(q,l_id+1,r_id-1){
		    sm1+=sum[q][0];
	    	sm2+=sum[q][1];
	    	sm3+=sum[q][2];
		}
	}
	sm1=(sm1%mod+mod)%mod,sm2=(sm2%mod+mod)%mod,sm3=(sm3%mod+mod)%mod;
	printf("%d %d %d\n",(int)sm1,(int)sm2,(int)sm3);
}
bool cur2;
int main(){
//	cerr<<(&cur1-&cur2)/1024.0/1024;
	freopen("magic.in","r",stdin);
	freopen("magic.out","w",stdout);
    in(n);
    rep(q,1,n)in(A[q]),in(B[q]),in(C[q]);
    in(m);
	blk=sqrt(n)/3+1;
	for(int q=0;q<=n;q+=blk)an[q/blk][0]={1,0,0,0},an[q/blk][1]={0,1,0,0},an[q/blk][2]={0,0,1,0};
	rep(q,1,n)ad(sum[q/blk][0],A[q]),ad(sum[q/blk][1],B[q]),ad(sum[q/blk][2],C[q]);
	int ty,l,r,v; 
    rep(q,1,m){
	    in(ty),in(l),in(r);
	    if(ty==4||ty==5||ty==6)in(v);
	    if(ty==1)operator_1(l,r);
		else if(ty==2)operator_2(l,r);
	    else if(ty==3)operator_3(l,r);
	    else if(ty==4)operator_4(l,r,v);
	    else if(ty==5)operator_5(l,r,v);
	    else if(ty==6)operator_6(l,r,v);
	    else query(l,r);
	}
    return 0;
}
posted @ 2019-08-01 16:36  Eeis  阅读(211)  评论(0编辑  收藏  举报