一个小问题
查看原帖
一个小问题
448873
Pig_py楼主2023/8/17 12:07
#include<bits/stdc++.h>
using namespace std;
//#define int long long
// 记得开 long long
int n,Q;
const int mod=998244353;
struct Matrix{
    int n,m;
    long long z[5][5];
    Matrix(){
        n=0;
        m=0;
        memset(z,0,sizeof z);
    }
};
struct Segment_tree{
    Matrix a,tag;
}Tree[1000005];
struct Ball{
	long long u,v,w;
}ball[250005];
Matrix operator*(const Matrix &m1,const Matrix &m2){
    Matrix m3;
    m3.n=m1.n;
    m3.m=m2.m;
    for(int i=0;i<=m3.n;i++){
        for(int j=0;j<=m3.m;j++){
            for(int k=0;k<=m1.m;k++){
                m3.z[i][j]+=m1.z[i][k]%mod*m2.z[k][j]%mod;
                m3.z[i][j]%=mod;
            }
        }
    }
    return m3;
}
int ls(int p){return p*2;}
int rs(int p){return p*2+1;}
void pushdown(int p,int l,int r){
	if(l!=r){
	    Tree[ls(p)].tag=Tree[ls(p)].tag*Tree[p].tag;
	    Tree[ls(p)].a=Tree[p].tag*Tree[ls(p)].a;
	    Tree[rs(p)].tag=Tree[rs(p)].tag*Tree[p].tag;		
	    Tree[rs(p)].a=Tree[p].tag*Tree[rs(p)].a;
	}
	for(int i=1-1;i<=5-1;i++){
	    for(int j=1-1;j<=5-1;j++){
	        if(i==j)Tree[p].tag.z[i][j]=1;
	        else Tree[p].tag.z[i][j]=0;
	    }
	}    
}
void pushup(int p){
    Tree[p].a.z[1-1][1-1]=((Tree[ls(p)].a.z[1-1][1-1]%mod)+(Tree[rs(p)].a.z[1-1][1-1]%mod))%mod;
    Tree[p].a.z[2-1][1-1]=((Tree[ls(p)].a.z[2-1][1-1]%mod)+(Tree[rs(p)].a.z[2-1][1-1]%mod))%mod;
    Tree[p].a.z[3-1][1-1]=((Tree[ls(p)].a.z[3-1][1-1]%mod)+(Tree[rs(p)].a.z[3-1][1-1]%mod))%mod;
}
void Build_tree(int p,int l,int r){
	if(l>r)return;
    Tree[p].a.n=5-1;
    Tree[p].a.m=1-1;
    Tree[p].tag.n=5-1;
    Tree[p].tag.m=5-1;
    Tree[p].tag.z[1-1][1-1]=1;
    Tree[p].tag.z[2-1][2-1]=1;
    Tree[p].tag.z[3-1][3-1]=1;
    Tree[p].tag.z[4-1][4-1]=1;
    Tree[p].tag.z[5-1][5-1]=1;
    Tree[p].a.z[5-1][1-1]=1;
    Tree[p].a.z[4-1][1-1]=r-l+1;
    if(l==r){
    	Tree[p].a.z[1-1][1-1]=ball[l].u%mod;
    	Tree[p].a.z[2-1][1-1]=ball[l].v%mod;
    	Tree[p].a.z[3-1][1-1]=ball[l].w%mod;
        return;
    }
    int mid=(l+r)/2;
    Build_tree(ls(p),l,mid);
    Build_tree(rs(p),mid+1,r);
    pushup(p);
}
bool check1(int l1,int r1,int l2,int r2){
    if(l1>=l2&&l1<=r2)return true;
    if(r1>=l2&&r1<=r2)return true;
    if(l2>=l1&&l2<=r1)return true;
    if(r2>=l1&&r2<=r1)return true;
    return false;
}
void Amend(int p,int l,int r,int ql,int qr,Matrix change){
	if(l>r||ql>qr)return;
    if(l>=ql&&r<=qr){
/*    	printf("p:%d l:%d r:%d ql:%d qr:%d\n",p,l,r,ql,qr);
    	puts("a1:");
    	for(int i=1;i<=5;i++){
    		printf("%d\n",Tree[p].a.z[i][1]);
		}*/
    	Tree[p].a=change*Tree[p].a;
/*    	puts("a2:");
    	for(int i=1;i<=5;i++){
    		printf("%d\n",Tree[p].a.z[i][1]);
		}  */  	
    	Tree[p].tag=Tree[p].tag*change;
        return;
    }
    pushdown(p,l,r);
    int mid=(l+r)/2;
    if(check1(l,mid,ql,qr))Amend(ls(p),l,mid,ql,qr,change);
    if(check1(mid+1,r,ql,qr))Amend(rs(p),mid+1,r,ql,qr,change);
    pushup(p);
}
pair<long long,pair<long long,long long> >Query(int p,int l,int r,int ql,int qr){
	if(l>r||ql>qr)return {0,{0,0}};
	if(l>=ql&&r<=qr){
		return {Tree[p].a.z[1-1][1-1]%mod,{Tree[p].a.z[2-1][1-1]%mod,Tree[p].a.z[3-1][1-1]%mod}};
	}
    pushdown(p,l,r);
    pair<long long,pair<long long,long long> > res={0,{0,0}};
    pair<long long,pair<long long,long long> > add={0,{0,0}};
    int mid=(l+r)/2;
    if(check1(l,mid,ql,qr)){
        add=Query(ls(p),l,mid,ql,qr);
        res.first+=add.first%mod;
        res.first%=mod;
        res.second.first+=add.second.first%mod;
        res.second.first%=mod;
        res.second.second+=add.second.second%mod;
        res.second.second%=mod;
        add={0,{0,0}};        
    }
    if(check1(mid+1,r,ql,qr)){
        add=Query(rs(p),mid+1,r,ql,qr);
        res.first+=add.first%mod;
        res.first%=mod;
        res.second.first+=add.second.first%mod;
        res.second.first%=mod;
        res.second.second+=add.second.second%mod;
        res.second.second%=mod;        
    }
    return res;
}
Matrix change;
signed main(){
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
    	scanf("%lld%lld%lld",&ball[i].u,&ball[i].v,&ball[i].w);
    	ball[i].u%=mod;
    	ball[i].v%=mod;
    	ball[i].w%=mod;
    }
    Build_tree(1,1,n);
    scanf("%d",&Q);
    while(Q--){
        int opt,l,r;
        long long v;
        scanf("%d%d%d",&opt,&l,&r);
        if(opt>=4&&opt<=6)scanf("%lld",&v);
        change.n=4;
        change.m=4;
        for(int i=0;i<=4;i++){
        	for(int j=0;j<=4;j++){
        		if(i==j)change.z[i][j]=1;
        		else change.z[i][j]=0;
			}
		}
        if(opt==1){
            change.z[1-1][2-1]=1;
            Amend(1,1,n,l,r,change);
        }
        else if(opt==2){
            change.z[2-1][3-1]=1;
            Amend(1,1,n,l,r,change);
        }
        else if(opt==3){
            change.z[3-1][1-1]=1;
            Amend(1,1,n,l,r,change);
        }
        else if(opt==4){
            change.z[1-1][4-1]=v%mod;
            Amend(1,1,n,l,r,change);
        }
        else if(opt==5){
            change.z[2-1][2-1]=v%mod;
            Amend(1,1,n,l,r,change);
        }
        else if(opt==6){
            change.z[3-1][3-1]=0;
            change.z[3-1][4-1]=v%mod;
            Amend(1,1,n,l,r,change);
        }
        else{
            auto ans=Query(1,1,n,l,r);
            printf("%lld %lld %lld\n",ans.first%mod,ans.second.first%mod,ans.second.second%mod);
        }
    }
}
/*
[1 0 0 0 0]      [A]
[0 1 0 0 0]      [B]
[0 0 1 0 0]  ×  [C]
[0 0 0 1 0]      [l]
[0 0 0 0 1]      [1]
3
1 2 3
4 2 1
5 3 2
6
7 2 3
1 1 3
2 2 2
6 1 2 4
4 2 3 16
7 2 3


1
8 10 1
2
5 1 1 5 
7 1 1
*/

这份代码只要 mm 一大就会莫名其妙 WA.

求调。

2023/8/17 12:07
加载中...