zoukankan      html  css  js  c++  java
  • bzoj3939 【USACO 2015 FEB GOLD 】cow hopscotch

    Description
    就像人类喜欢玩“跳房子”的游戏,农民约翰的奶牛已经发明了该游戏的一个变种自己玩。由于笨拙的动物体重近一吨打,牛跳房子几乎总是以灾难告终,但这是没有阻止奶牛几乎每天下午玩这个游戏。
    游戏的矩阵共有R*C格(2 <= R <= 750,2 <= C <= 750),其中每一格是个正方形并被标记为一个整数K( 1 < = K <= R * C)。游戏是牛开始在左上角最后向右下角移动到的一个跳跃序列,牛从一个格子只能跳到在他的严格右下方(行列都要大于当前位置)与当前格子权值不同的格子上。请帮助奶牛计算不同可能的有效跳跃序列的数量。
    Input
    第一行三个整数 R, C, K.
    以下R行,每行 C个整数.
    Output
    输出方案数,由于数太大,请对答案取模 1000000007.
    Sample Input
    4 4 4
    1 1 1 1
    1 3 2 1
    1 2 4 1
    1 1 1 1
    Sample Output
    5

    正解:分治or线段树


    对于列分治,每次分治时,先把≤mid的区间处理,再统计≤mid的答案,然后加入>mid的区间中,复杂度O(n*m log n)。

    取模的话,%一波r_64大神。。


    //It is made by wfj_2048~
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #define inf (1<<30)
    #define il inline
    #define RG register
    #define ll long long
    #define rhl 1000000007
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    
    using namespace std;
    
    int a[760][760],vis[562510],n,m,k,T;
    ll f[760][760],s[562510];
    
    il int gi(){
        RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
        if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    }
    
    il void solve(RG int l,RG int r){
        if (l==r) return; RG int mid=(l+r)>>1;
        solve(l,mid); T++; RG ll sum=0;
        for (RG int i=2;i<=n;++i){
    	for (RG int j=l;j<=mid;++j){
    	    if (vis[a[i-1][j]]!=T) s[a[i-1][j]]=0,vis[a[i-1][j]]=T;
    	    (sum+=f[i-1][j])%=rhl,(s[a[i-1][j]]+=f[i-1][j])%=rhl;
    	}
    	for (RG int j=mid+1;j<=r;++j){
    	    if (vis[a[i][j]]!=T) s[a[i][j]]=0,vis[a[i][j]]=T;
    	    (f[i][j]+=sum-s[a[i][j]]+rhl)%=rhl;
    	}
        }
        solve(mid+1,r); return;
    }
    
    il void work(){
        n=gi(),m=gi(),k=gi(); f[1][1]=1;
        for (RG int i=1;i<=n;++i)
    	for (RG int j=1;j<=m;++j) a[i][j]=gi();
        solve(1,m); printf("%lld
    ",f[n][m]); return;
    }
    
    int main(){
        File("cowhouse");
        work();
        return 0;
    }
    


  • 相关阅读:
    vim介绍 & vim颜色显示和移动光标& vim一般模式下移动光标 & vim一般模式下复制、剪切和粘贴
    lvm 详解 磁盘故障小案例
    磁盘格式化、磁盘挂载、手动增加swap空间
    df du 磁盘分区
    su sudo 限制root远程登录
    usermod 用户密码管理 mkpasswd
    顺序查找,二分法查找,插值查找算法实现及分析
    完全二叉树的构建及三种遍历
    Mybatis由于类型转换出现的问题
    delimiter解释
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6416592.html
Copyright © 2011-2022 走看看