ZJOI2009 對稱的正方形(矩陣雜湊 二分)

2021-09-01 02:36:33 字數 3510 閱讀 9593

時間限制:1000ms

1000ms

1000ms

記憶體限制:128mb

128 mb

128m

b

問題描述

o re

zorez

orez

很喜歡蒐集一些神秘的資料,並經常把它們排成乙個矩陣進行研究。最近,ore

zorez

orez

又得到了一些資料,並已經把它們排成了乙個n

nn行m

mm列的矩陣。通過觀察,ore

zorez

orez

發現這些資料蘊涵了乙個奇特的數,就是矩陣中上下對稱且左右對稱的正方形子矩陣的個數。 ore

zorez

orez

自然很想知道這個數是多少,可是矩陣太大,無法去數。只能請你編個程式來計算出這個數。

輸入格式

檔案的第一行為兩個整數n

nn和m

mm。接下來n

nn行每行包含m

mm個正整數,表示ore

zorez

orez

得到的矩陣。

輸出格式

檔案中僅包含乙個整數ans

we

ranswer

answer

,表示矩陣中有ans

we

ranswer

answer

個上下左右對稱的正方形子矩陣。

樣例輸入

5 555

554442

224444

444443

331114

444443

333335

553333

333333

331115

553333

334442

221112

22444

樣例輸出

27

2727

資料範圍

對於30

3030

%的資料 n,m

≤100

n,m≤100

n,m≤10

0對於100

10010

0%的資料 n,m

≤1000

n,m≤1000

n,m≤10

00,矩陣中的數的大小≤10

9≤10^9

≤109

聽說有很多神仙是用man

ache

rmanacher

manach

er做的 ,然而本蒟蒻並不會 。

所以我們用一種比較簡單粗暴且易於理解的演算法——has

hhash

hash

來替代。(說白了就是弱)

首先我們會發現兩個很 (顯然且) 有用的性質:

如果乙個正方形子矩陣是對稱的且邊長》

2>2

>

2,那麼比它小一圈的正方形子矩陣也一定是對稱的。

正方形子矩陣的對稱中心至多只有o(2

nm

)o(2nm)

o(2nm)

個那麼我們可以列舉正方形子矩陣的對稱中心,並二分此對稱中心的最大邊長。

至於判定該正方形子矩陣是否對稱,我們可以通過矩陣hash來解決。

設乙個矩陣a

[1..i]

[1..j]

a[1..i][1..j]

a[1..i

][1.

.j]的has

hhash

hash

值為σ p1

i∗p2

j∗a[

i][j

]σp_1^i*p_2^j*a[i][j]

σp1i​∗

p2j​

∗a[i

][j]

我們把原矩陣、原矩陣上下翻轉、原矩陣左右翻轉分別做一次has

hhash

hash

,判定時只要把對應矩陣的has

hhash

hash

值用二維字首和求出來並簡單處理一下行差、列差對p1,

p2

p_1,p_2

p1​,p2

​乘方次數的影響之後判斷是否相等即可。 tip

s:

tips:

tips:

本題時限較緊,請提前預處理p1i

,p2j

p_1^i,p_2^j

p1i​,p

2j​如果你對自己的常數不是非常自信的話請不要寫雙has

hhash

hash

,寫了也不要用pai

rpair

pair

cyl大佬已經身先士卒地t了

別把m

mm打成n

nn,本蒟蒻對此已經不想說什麼了

列舉偶數邊長時不一定有答案

#include

#define ll long long

using

namespace std;

const

int maxn =

1005

;const

int p1 =29;

const

int p2 =31;

const

int mod =

1e9+7;

int n , m;

int a[maxn]

[maxn]

, b[maxn]

[maxn]

, c[maxn]

[maxn]

;ll pow_x[maxn]

, pow_y[maxn]

;int

min(

int x ,

int y)

intread()

void

pow_init()

struct hash

} ll sum

(int bx ,

int by ,

int ex ,

int ey)

}hash1 , hash2 , hash3;

bool

check1

(int len ,

int i ,

int j)

bool

check2

(int len ,

int i ,

int j)

intmain()

ans +

= l +1;

}for

(int i =

1;i < n;i++

)for

(int j =

1;j < m;j++

) ans +

= res +1;

}printf

("%d\n"

,ans)

;return0;

}

P2601 ZJOI2009 對稱的正方形

description 題面 給你一張 n m 的數字表,問其中有多少個上下對稱且左右對稱的正方形。solution 這道題真的噁心,首先學習一下二維雜湊,但在學習二維雜湊之前,我們先來看乙個問題 給你乙個長度為 n 的字串和 q 組詢問,每組詢問是兩個位置和兩個長度代表兩個子串,問這兩個子串是否相...

專案二 對稱矩陣壓縮儲存的實現與應用

問題及 2015,煙台大學計算機與控制工程學院 完成日期 2015年10月26日 問題描述 用壓縮形式儲存對稱矩陣,實現下面的操作並測試.1 標頭檔案 ifndef tup h included define tup h included define n 4 void init int b int...

第九周專案二 對稱矩陣壓縮儲存的實現與應用1

煙台大學計算機與控制工程學院 時間2015年12月14日 問題描述 用壓縮形式儲存對稱矩陣,實現下面的操作並測試 void init int b 為n階對稱矩陣初始化儲存資料的一維陣列b int value int b,int i,int j 返回儲存在b m 中,對應二維陣列a i j 的值 vo...