[LOJ#2980][THUSCH2017]大魔法師(線段樹+矩陣)
阿新 • • 發佈:2019-01-18
family tin per clu esp print ret 區間 algo
每個線段樹維護一個行向量[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 }
[LOJ#2980][THUSCH2017]大魔法師(線段樹+矩陣)