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\n",f[n][m]); return;
}

int main(){
    File("cowhouse");
    work();
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章