[LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)

每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然。

以及此题卡常,稍微哪里写丑了就能100->45。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define ls (x<<1)
 6 #define rs (ls|1)
 7 #define lson ls,L,mid
 8 #define rson rs,mid+1,R
 9 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
10 using namespace std;
11 
12 const int N=250010,mod=998244353;
13 int n,T,op,l,r,x,a[N],b[N],c[N];
14 
15 int rd(){
16     int x=0; char ch=getchar(); bool f=0;
17     while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
18     while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
19     return f ? -x : x;
20 }
21 
22 inline void inc(int &x,int y){ x+=y; x-=x>=mod ? mod : 0; }
23 
24 struct Mat{
25     int a[4][4];
26     Mat (){ memset(a,0,sizeof(a)); }
27 }I,A[N],v[N<<2],tag[N<<2];
28 
29 Mat operator +(const Mat &a,const Mat &b){
30     Mat c=a;
31     rep(i,0,3) inc(c.a[0][i],b.a[0][i]);
32     return c;
33 }
34 
35 void put(int x,const Mat &a){
36     Mat nw;
37     rep(i,0,3) rep(k,0,3) if (a.a[i][k])
38         inc(nw.a[0][k],1ll*v[x].a[0][i]*a.a[i][k]%mod);
39     v[x]=nw; nw=Mat();
40     rep(i,0,3) rep(j,0,3) if (tag[x].a[i][j]) rep(k,0,3) if (a.a[j][k])
41         inc(nw.a[i][k],1ll*tag[x].a[i][j]*a.a[j][k]%mod);
42     tag[x]=nw;
43 }
44 
45 void push(int x){ put(ls,tag[x]); put(rs,tag[x]); tag[x]=I; }
46 
47 void build(int x,int L,int R){
48     tag[x]=I;
49     if (L==R){ v[x]=A[L]; return; }
50     int mid=(L+R)>>1;
51     build(lson); build(rson); v[x]=v[ls]+v[rs];
52 }
53 
54 void mdf(int x,int L,int R,int l,int r,Mat &k){
55     if (L==l && r==R){ put(x,k); return; }
56     int mid=(L+R)>>1; push(x);
57     if (r<=mid) mdf(lson,l,r,k);
58     else if (l>mid) mdf(rson,l,r,k);
59         else mdf(lson,l,mid,k),mdf(rson,mid+1,r,k);
60     v[x]=v[ls]+v[rs];
61 }
62 
63 Mat que(int x,int L,int R,int l,int r){
64     if (L==l && r==R){ return v[x]; }
65     int mid=(L+R)>>1; push(x);
66     if (r<=mid) return que(lson,l,r);
67     else if (l>mid) return que(rson,l,r);
68         else return que(lson,l,mid)+que(rson,mid+1,r);
69 }
70 
71 int main(){
72     freopen("magic.in","r",stdin);
73     freopen("magic.out","w",stdout);
74     n=rd();
75     rep (i,0,3) I.a[i][i]=1;
76     rep (i,1,n){ A[i].a[0][3]=1; rep (j,0,2) A[i].a[0][j]=rd(); }
77     build(1,1,n);
78     for (T=rd(); T--; ){
79         op=rd(); l=rd(); r=rd(); Mat s=I;
80         if (op>=4 && op<=6) x=rd();
81         if (op==7){
82             Mat res=que(1,1,n,l,r);
83             printf("%d %d %d\n",res.a[0][0],res.a[0][1],res.a[0][2]);
84             continue;
85         }
86         if (op==1) s.a[1][0]=1;
87         if (op==2) s.a[2][1]=1;
88         if (op==3) s.a[0][2]=1;
89         if (op==4) s.a[3][0]=x;
90         if (op==5) s.a[1][1]=x;
91         if (op==6) s.a[2][2]=0,s.a[3][2]=x;
92         mdf(1,1,n,l,r,s);
93     }
94     return 0;
95 }

 

posted @ 2019-01-18 20:44  HocRiser  阅读(408)  评论(0编辑  收藏  举报