計蒜客 UCloud 的安全秘鑰(困難)(雜湊)

2022-09-17 22:06:15 字數 2273 閱讀 2185

ucloud 的安全秘鑰(困難)

編輯**

每個 ucloud 使用者會構造乙個由數字序列組成的秘鑰,用於對伺服器進行各種操作。作為一家安全可信的雲計算平台,秘鑰的安全性至關重要。因此,ucloud 每年會對使用者的秘鑰進行安全性評估,具體的評估方法如下:

ucloud 每年會收集若干不安全秘鑰,這些秘鑰組成了不安全秘鑰集合 tt。對於乙個秘鑰 ss 和集合 tt 中的秘鑰 tt來說,它們的相似值定義為:ss 的所有連續子串中與 tt 近似匹配的個數。相似值越高,說明秘鑰 ss 越不安全。對於不安全秘鑰集合 tt 中的每個秘鑰 tt,你需要輸出它和秘鑰 ss 的相似值,用來對使用者秘鑰的安全性進行分析。

第一行包含乙個正整數 nn,表示 ss 串的長度。

第二行包含 nn 個正整數 s_1,s_2,...,s_n(1\leq s_i\leq n)s​1​​,s​2​​,...,s​n​​(1≤s​i​​≤n),表示 ss 串。

接下來一行包含乙個正整數 mm,表示詢問的個數。

接下來 mm 個部分:

每個部分第一行包含乙個正整數 k(1\leq k\leq n)k(1≤k≤n),表示每個 tt 串的長度。

每個部分第二行包含 kk 個正整數 t_1,t_2,...,t_k(1\leq t_i\leq n)t​1​​,t​2​​,...,t​k​​(1≤t​i​​≤n),表示 tt 中的乙個串 tt。

輸入資料保證 tt 中所有串長度之和不超過 200000200000。

對於簡單版本:1\leq n,m\leq 1001≤n,m≤100;

對於中等版本:1\leq n\leq 50000,1\leq m\leq 5001≤n≤50000,1≤m≤500;

對於困難版本:1 \le n \le 50000, 1 \le m \le 1000001≤n≤50000,1≤m≤100000。

輸出 mm 行,每行乙個整數,即與 tt 中每個串 tt 近似匹配的 ss 的子串數量。

樣例輸入

5

2 3 1 3 234

3 2 1 3

21 3

23 2

樣例輸出

222

【分析】給你乙個原始陣列,陣列裡每個數都<=n;然後k次詢問,每次詢問給出乙個新的陣列,問你原始陣列中有多少連續子串是給定陣列的

一種重新排列。

對於中等難度的,可以雙指標搞一下,但是對於困難的就不會了,看了題解才知道...對於詢問給定的陣列的總長最大為2000000,而每次給

定的陣列最長為50000.也就是說對於乙個陣列的長度m,不同的m的種數最多才650種。那麼我們可以離線,將同種長度的存在一起。然後將

原始的陣列的各種長度的m的雜湊值算出來,然後排個序,對於此長度的詢問的陣列就可以根據雜湊值二分來統計答案了。那麼現在的問題是

怎麼雜湊...看了題解才知道後還有這種雜湊的姿勢,給每個數隨機乙個16位的數,就是ull rand()*rand()...學習到新知識了。

#include #define mp make_pair

#define pb push_back

#define met(a,b) memset(a,b,sizeof a)

using

namespace

std;

typedef

long

long

ll;typedef unsigned

long

long

ull;

typedef pair

pii;

const

int n = 2e5+5

;const

int mod = 1e9+7

;int

n,m,k,u;

inta[n];

intb[n],ans[n];

ll has[n];

ull sum[n];

vector

int> >vec[n];

vector

c;vector

q;int

main()

scanf("%d

",&k);

for(int i=1;i<=k;i++)

vec[m].pb(mp(s,i));

}for(int

x:c)

}else

}sort(q.begin(),q.end());

for(pairint>p : vec[x])}}

for(int i=1;i<=k;i++)

return0;

}

計蒜客 單獨的數字

給定乙個陣列 a,除了乙個數出現一次之外,其餘數都出現三次。找出出現一次的數。如 找出 7。你的演算法只能是線性時間的複雜度,並且不能使用額外的空間哦 輸入格式 第一行輸入乙個數n 1 n 500 代表陣列的長度。接下來一行輸入 n 個 int 範圍內 2147483648 2147483647 的...

計蒜客 單獨的數字

給定乙個陣列 a a,除了乙個數出現一次之外,其餘數都出現三次。找出出現一次的數。如 找出 77。你的演算法只能是線性時間的複雜度,並且不能使用額外的空間哦 第一行輸入乙個數 n 1 leq n leq 500 n 1 n 500 代表陣列的長度。接下來一行輸入 n n 個 int 範圍內 2147...

計蒜客 單獨的數字

單獨的數字 給定乙個陣列 aa a,除了乙個數出現一次之外,其餘數都出現三次。找出出現一次的數。如 找出 777。你的演算法只能是線性時間的複雜度,並且不能使用額外的空間哦 第一行輸入乙個數 n 1 n 500 n 1 leq n leq 500 n 1 n 500 代表陣列的長度。接下來一行輸入 ...