2019牛客暑期多校训练营(第二场)E MAZE(线段树维护矩阵+DP)

题目链接: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('\n')
  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 }
代码在这里!

 

posted @ 2019-08-12 00:21  wuliking  阅读(179)  评论(0编辑  收藏  举报