「THUSCH 2017」大魔法师 解题报告

「THUSCH 2017」大魔法师

狗体面太长,帖链接


思路,维护一个\(1\times 4\)的答案向量表示\(A,B,C,len\),最后一个表示线段树上区间长度,然后每次的操作都有一个转移矩阵,随便搞搞就成了,卡常


Code:

#include <cstdio>
#include <cstring>
namespace io
{
    const int SIZE=(1<<21)+1;
    char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];
    int f,qr;
    // getchar
    #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    // print the remaining part
    inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    // putchar
    inline void putc(char x){*oS++=x;if(oS==oT)flush();}
    // input a signed integer
    template <class I>
    inline void read(I &x)
    {
        for(f=1,c=gc();c<'0'||c>'9';c=gc()) if(c=='-') f=-1;
        for(x=0;c<='9'&&c>='0';c=gc()) x=x*10+(c&15);x*=f;
    }
    // print a signed integer
    template <class I>
    inline void print(I &x)
    {
        if(!x)putc('0');if(x<0) putc('-'),x=-x;
        while(x)qu[++qr]=x%10+'0',x/=10;
        while(qr)putc(qu[qr--]);
    }
    //no need to call flush at the end manually
    struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io::read;
using io::putc;
using io::print;
const int N=250010;
const int mod=998244353;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
#define mul(a,b) ((int)(1ll*(a)*(b)%mod))
struct matrix
{
    int dx[4][4];
    matrix(){memset(dx,0,sizeof dx);}
    matrix friend operator +(matrix a,matrix b)
    {
        for(int i=0;i<=3;i++)
            a.dx[0][i]=add(a.dx[0][i],b.dx[0][i]);
        return a;
    }
    bool friend operator ==(matrix a,matrix b)
    {
        for(int i=0;i<=3;i++)
            for(int j=0;j<=3;j++)
                if(a.dx[i][j]!=b.dx[i][j])
                    return false;
        return true;
    }
}I,t,yuy[N<<2],tag[N<<2];
int n,m;
#define ls id<<1
#define rs id<<1|1
void build(int id,int l,int r)
{
    tag[id]=I;
    if(l==r)
    {
        read(yuy[id].dx[0][0]),read(yuy[id].dx[0][1]),read(yuy[id].dx[0][2]);
        yuy[id].dx[0][3]=1;
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid),build(rs,mid+1,r);
    yuy[id]=yuy[ls]+yuy[rs];
}
void beecute(int id,matrix &a)
{
    matrix bee=matrix();
    for(int i=0;i<=3;i++)
        for(int j=0;j<=3;j++)
            bee.dx[0][i]=add(bee.dx[0][i],mul(yuy[id].dx[0][j],a.dx[j][i]));
    yuy[id]=bee;
    memset(bee.dx,0,sizeof bee.dx);
    for(int i=0;i<=3;i++)
        for(int j=0;j<=3;j++)
        {
            bee.dx[i][j]=add(bee.dx[i][j],mul(tag[id].dx[i][0],a.dx[0][j]));
            bee.dx[i][j]=add(bee.dx[i][j],mul(tag[id].dx[i][1],a.dx[1][j]));
            bee.dx[i][j]=add(bee.dx[i][j],mul(tag[id].dx[i][2],a.dx[2][j]));
            bee.dx[i][j]=add(bee.dx[i][j],mul(tag[id].dx[i][3],a.dx[3][j]));
        }
    tag[id]=bee;
}
void pushdown(int id)
{
    if(tag[id]==I) return;
    beecute(ls,tag[id]);
    beecute(rs,tag[id]);
    tag[id]=I;
}
void change(int id,int L,int R,int l,int r)
{
    if(l==L&&r==R){beecute(id,t);return;}
    pushdown(id);
    int Mid=L+R>>1;
    if(r<=Mid) change(ls,L,Mid,l,r);
    else if(l>Mid) change(rs,Mid+1,R,l,r);
    else change(ls,L,Mid,l,Mid),change(rs,Mid+1,R,Mid+1,r);
    yuy[id]=yuy[ls]+yuy[rs];
}
matrix query(int id,int L,int R,int l,int r)
{
    if(l==L&&r==R) return yuy[id];
    pushdown(id);
    int Mid=L+R>>1;
    if(r<=Mid) return query(ls,L,Mid,l,r);
    else if(l>Mid) return query(rs,Mid+1,R,l,r);
    else return query(ls,L,Mid,l,Mid)+query(rs,Mid+1,R,Mid+1,r);
}
int main()
{
    read(n);
    for(int i=0;i<=3;i++) I.dx[i][i]=1;
    build(1,1,n);
    read(m);
    for(int op,l,r,v,i=1;i<=m;i++)
    {
        read(op),read(l),read(r);
        if(op==7)
        {
            t=query(1,1,n,l,r);
            print(t.dx[0][0]);
            putc(' ');
            print(t.dx[0][1]);
            putc(' ');
            print(t.dx[0][2]);
            putc('\n');
            continue;
        }
        t=I;
        if(op==1) t.dx[1][0]=1;
        else if(op==2) t.dx[2][1]=1;
        else if(op==3) t.dx[0][2]=1;
        else if(op==4) read(v),t.dx[3][0]=v;
        else if(op==5) read(v),t.dx[1][1]=v;
        else read(v),t.dx[3][2]=v,t.dx[2][2]=0;
        change(1,1,n,l,r);
    }
    return 0;
}

2019.1.19

posted @ 2019-01-19 18:54  露迭月  阅读(170)  评论(0编辑  收藏  举报