zoukankan      html  css  js  c++  java
  • #线段树,矩阵乘法#洛谷 7453 [THUSCH2017] 大魔*

    题目


    分析

    首先考虑如果修改操作都是单点修改怎么做,
    以第一种修改为例那么就是

    [left[egin{matrix}A\B\C\1end{matrix} ight] imes left[egin{matrix}1,0,0,0\1,1,0,0\0,0,1,0\0,0,0,1end{matrix} ight]=left[egin{matrix}A+B\B\C\1end{matrix} ight] ]

    同理其它操作也能通过乘矩阵来维护,

    考虑区间修改时询问为求和,那么只需要开懒标记即可

    时间复杂度 (O(4^3Qlog_2{n}))


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=250011,mod=998244353;
    typedef long long lll; int n;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans; 
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    struct maix{
    	lll p[4][4];
    	inline maix operator *(const maix &t)const{
    	    rr maix _t;
    	    for (rr int i=0;i<4;++i)
    	    for (rr int j=0;j<4;++j){
    	    	_t.p[i][j]=0;
    	    	for (rr int k=0;k<4;++k)
    	    	    _t.p[i][j]+=p[i][k]*t.p[k][j];
    	    	_t.p[i][j]%=mod;
    		}
    		return _t;
    	}
    }u,lazy[N<<2];
    struct Four{
        lll p[4];
        inline Four operator +(const Four &t)const{
    	    rr Four _t;
    	    for (rr int i=0;i<4;++i)
    	        _t.p[i]=p[i]+t.p[i]>=mod?p[i]+t.p[i]-mod:p[i]+t.p[i];
    	    return _t;
    	}
    }ANS,w[N<<2];
    inline bool Is_Unit(maix A){
    	for (rr int i=0;i<4;++i)
    	for (rr int j=0;j<4;++j)
    	    if (A.p[i][j]!=u.p[i][j]) return 0;
    	return 1;
    }
    inline Four mul(Four A,maix B){
    	rr Four C;
    	for (rr int i=0;i<4;++i){
    		C.p[i]=0;
    		for (rr int j=0;j<4;++j)
    		    C.p[i]+=A.p[j]*B.p[j][i];
    		C.p[i]%=mod;
    	}
    	return C;
    }
    inline void pdown(int k){
    	w[k<<1]=mul(w[k<<1],lazy[k]);
    	lazy[k<<1]=lazy[k<<1]*lazy[k];
    	w[k<<1|1]=mul(w[k<<1|1],lazy[k]);
    	lazy[k<<1|1]=lazy[k<<1|1]*lazy[k];
    	lazy[k]=u;
    }
    inline void build(int k,int l,int r){
    	lazy[k]=u;
    	if (l==r){
    		for (rr int i=0;i<3;++i)
    		    w[k].p[i]=iut();
    		w[k].p[3]=1;
    		return;
    	}
    	rr int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	w[k]=w[k<<1]+w[k<<1|1];
    }
    inline void update(int k,int l,int r,int x,int y,maix z){
        if (l==x&&r==y) {w[k]=mul(w[k],z),lazy[k]=lazy[k]*z; return;} 
        rr int mid=(l+r)>>1; if (!Is_Unit(lazy[k])) pdown(k);
        if (y<=mid) update(k<<1,l,mid,x,y,z);
        else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
            else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
        w[k]=w[k<<1]+w[k<<1|1];
    }
    inline Four query(int k,int l,int r,int x,int y){
    	if (l==x&&r==y) return w[k];
    	rr int mid=(l+r)>>1; if (!Is_Unit(lazy[k])) pdown(k);
        if (y<=mid) return query(k<<1,l,mid,x,y);
        else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
            else return query(k<<1,l,mid,x,mid)+query(k<<1|1,mid+1,r,mid+1,y);
    }
    signed main(){
    	for (rr int i=0;i<4;++i) u.p[i][i]=1;
    	n=iut(),build(1,1,n);
    	for (rr int Q=iut();Q;--Q){
    		rr int opt=iut(),l=iut(),r=iut(),w=0; rr maix z=u;
    		if (opt<7){
    			if (opt>3) w=iut();
    			switch (opt){
    				case 1:{
    					z.p[1][0]=1;
    					break;
    				}
    				case 2:{
    					z.p[2][1]=1;
    					break;
    				}
    				case 3:{
    					z.p[0][2]=1;
    					break;
    				}
    				case 4:{
    					z.p[3][0]=w;
    					break;
    				}
    				case 5:{
    					z.p[1][1]=w;
    					break;
    				}
    				case 6:{
    					z.p[2][2]=0,z.p[3][2]=w;
    					break;
    				}
    			}
    			update(1,1,n,l,r,z);
    		}
    		else{
    		    ANS=query(1,1,n,l,r);
    			for (rr int i=0;i<3;++i)
    			    print(ANS.p[i]),putchar(i==2?10:32);
    		}
    	}
        return 0;
    }
    
  • 相关阅读:
    为DataGrid 写一个 DropDownListColumn
    网页向女友告白和纪念日专用特效
    CentOS6.5 64位站点压力測试工具webbench
    RxJava系列之二 变换类操作符具体解释1
    C语言实现单链表节点的删除(带头结点)
    excel 补全全部空格
    Linux经常使用命令-文件搜索命令-文件搜索命令find
    错误代码: 1045 Access denied for user &#39;skyusers&#39;@&#39;%&#39; (using password: YES)
    Yocto tips (17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
    二叉树的基本使用
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15176409.html
Copyright © 2011-2022 走看看