zoukankan      html  css  js  c++  java
  • 常州day1p3

    给定一个 n 行 m 列的方格,每个格子里有一个正整数 a,1 ≤ a ≤ k,k ≤ n∗m 假设你当前时刻站在 (i,j) 这个格子里,你想要移动到 (x,y),那必须满足以下三个条件 1:i < x 2:j < y 3:第 i 行第 j 列格子里的数不等于第 x 行第 y 列格子里的数 求从 (1,1) 移动到 (n,m) 的不同的方案数 

    对于 100% 的数据,n,m ≤ 750

    容易想到f[i][j]=sigma(f[k][l]|a[k][l]!=a[i][j])

    我们可以容易的统计和颜色无关的情况然后去掉颜色相同的就可以了。

    于是我们对每一种颜色建立一颗权值线段树

    动态开点

    时间复杂度O(n^2logn)

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #define re register
    #define il inline
    using namespace std;
    const int N=1001,NN=8000001;
    const int mod=1000000007;
    int n,m,a[N][N],k,root[NN],lch[NN],rch[NN],cnt=0;
    int f[N][N],s[N][N],w[NN];
    il int read(){
        re int hs=0;re char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)){
            hs=(hs<<3)+(hs<<1)+c-'0';
            c=getchar(); 
        }
        return hs;
    }
    il void add(re int &i,re int l,re int r,re int p,re int v){
        if(i==0) i=(++cnt);
        w[i]=(w[i]+v)%mod;
        if(l==r) return;
        re int mid=(l+r)/2;
        if(p<=mid) add(lch[i],l,mid,p,v);
        else add(rch[i],mid+1,r,p,v); 
    }
    il int sum(re int i,re int l,re int r,re int p,re int q){
        if(!i) return 0;
        if(l==p&&r==q) return w[i];
        re int mid=(l+r)/2;
        if(q<=mid) return sum(lch[i],l,mid,p,q);
        if(mid<p) return sum(rch[i],mid+1,r,p,q);
        return (sum(lch[i],l,mid,p,mid)+sum(rch[i],mid+1,r,mid+1,q))%mod; 
    }
    int main(){
        freopen("hopscotch.in","r",stdin);
        freopen("hopscotch.out","w",stdout);
        n=read();m=read();k=read();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
                a[i][j]=read();
        }
        f[1][1]=1;add(root[a[1][1]],1,m,1,f[1][1]);
        for(int i=1;i<=m;i++) s[1][i]=1;
        for(int i=1;i<=n;i++) s[i][1]=1;
        for(int i=2;i<=n;i++){
            for(int j=2;j<=m;j++){
                f[i][j]=(s[i-1][j-1]-sum(root[a[i][j]],1,m,1,j-1)+mod)%mod;
                s[i][j]=(((s[i-1][j]+s[i][j-1])%mod+f[i][j])%mod-s[i-1][j-1]+mod)%mod;
                add(root[a[i-1][j]],1,m,j,f[i-1][j]);
            }
        }
        cout<<f[n][m]%mod;
        return 0;
    }
  • 相关阅读:
    mac 10.9 安装 gevent
    flash builder4.7 for Mac升级AIRSDK详解
    重走java--Step 3
    重走java--Step 2
    重走java---Step 1
    web初学之MVC
    web初学之JavaBean
    微信公众号开发之开发模式的启用——学习笔记
    微信公众号开发之开通账号——学习笔记
    web初学之request,session与application
  • 原文地址:https://www.cnblogs.com/ExiledPoet/p/5771471.html
Copyright © 2011-2022 走看看