题目链接:https://ac.nowcoder.com/acm/contest/882/E
题目大意&解题报告:
参考这篇博客,讲的很详细。
AC代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar(' ') 5 #define pb push_back 6 #define fi first 7 #define se second 8 #define fre1 freopen("1.txt","r",stdin) 9 #define fre2 freopen("2.txt","w",stdout) 10 #define debug cout<<"debug"<<endl 11 using namespace std; 12 template <typename T> 13 void read(T &res) { 14 bool flag=false;char ch; 15 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 16 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 17 flag&&(res=-res); 18 } 19 template <typename T> 20 void write(T x) { 21 if(x<0) putchar('-'),x=-x; 22 if(x>9) write(x/10); 23 putchar(x%10+'0'); 24 } 25 typedef long long ll; 26 const int maxn=50005; 27 const int N=60; 28 const int mod=1e9+7; 29 int n,m,q; 30 ll a[maxn][12]; 31 struct CYY { 32 #define ls (p<<1) 33 #define rs (p<<1|1) 34 #define mid ((l+r)>>1) 35 struct node { 36 ll m[12][12]; 37 }st[maxn<<2]; 38 ll add(ll a,ll b){ 39 return a+b >= mod ? a+b-mod : a+b; 40 } 41 ll mul(ll a,ll b) { 42 return a*b >= mod ? a*b%mod : a*b; 43 } 44 node Mmul(node a,node b) { 45 node c; 46 for(int i=1;i<=m;i++) 47 for(int j=1;j<=m;j++) { 48 c.m[i][j]=0; 49 for(int k=1;k<=m;k++) 50 c.m[i][j]=add(c.m[i][j],mul(a.m[i][k],b.m[k][j])); 51 } 52 return c; 53 } 54 void Mupd(int p,int x) { ///维护这一行的i到j的可行路 55 memset(st[p].m,0,sizeof(st[p].m)); 56 for(int i=1;i<=m;i++) 57 if(!a[x][i]) { 58 st[p].m[i][i]=1; 59 for(int j=i-1;j>=1&&!a[x][j];j--) 60 st[p].m[j][i]=1; 61 for(int j=i+1;j<=m&&!a[x][j];j++) 62 st[p].m[j][i]=1; 63 } 64 } 65 void build(int l,int r,int p) { 66 if(l==r) { 67 Mupd(p,l); ///乘法初矩阵更新 68 return ; 69 } 70 build(l,mid,ls); 71 build(mid+1,r,rs); 72 st[p]=Mmul(st[ls],st[rs]); ///回溯等于两个儿子矩阵的积 73 } 74 void upd(int l,int r,int x,int y,int p) { 75 if(l==r) { 76 Mupd(p,l); ///乘法初矩阵更新 77 return ; 78 } 79 if(x<=mid) upd(l,mid,x,y,ls); 80 else upd(mid+1,r,x,y,rs); 81 st[p]=Mmul(st[ls],st[rs]); ///回溯等于两个儿子矩阵的积 82 } 83 }cyy; 84 int main() 85 { 86 read(n);read(m);read(q); 87 for(int i=1;i<=n;i++) 88 for(int j=1;j<=m;j++) 89 scanf("%1d",&a[i][j]); 90 cyy.build(1,n,1); 91 while(q--) { 92 int oper,x,y; 93 read(oper);read(x);read(y); 94 if(oper==1) { 95 a[x][y]^=1; 96 cyy.upd(1,n,x,y,1); 97 } 98 else write(cyy.st[1].m[x][y]),pn; 99 } 100 return 0; 101 }