zoukankan      html  css  js  c++  java
  • 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('
    ')
      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 }
    代码在这里!
  • 相关阅读:
    设计原则
    最小路径和--p64--动态规划
    ssm实现数据库关键信息的动态加载
    最大二叉树--p654--递归构造
    城市天际线--p807
    长url转短url--p535
    从中序与后序遍历中构造二叉树-p106--数组,二叉树遍历
    n皇后问题--p52--回溯
    Markdown(editormd)语法解析成HTML
    NFA的实现
  • 原文地址:https://www.cnblogs.com/wuliking/p/11337416.html
Copyright © 2011-2022 走看看