UCloud 的安全秘鑰 (計蒜客初賽第五場)(待解決)
- 20.7%
每個 UCloud 用戶會構造一個由數字序列組成的秘鑰,用於對服務器進行各種操作。作為一家安全可信的雲計算平臺,秘鑰的安全性至關重要。因此,UCloud 每年會對用戶的秘鑰進行安全性評估,具體的評估方法如下:
首先,定義兩個由數字序列組成的秘鑰 aa 和 bb 近似匹配(\approx≈) 的關系。aa 和 bb 近似匹配當且僅當同時滿足以下兩個條件:
- |a|=|b|∣a∣=∣b∣,即 aa 串和 bb 串長度相等。
- 對於每種數字 cc,cc 在 aa 中出現的次數等於 cc 在 bb 中出現的次數。
此時,我們就稱 aa 和 bb 近似匹配,即 a \approx ba≈b。例如,(1,3,1,1,2)\approx(2,1,3,1,1)(1,3,1,1,2)≈(2,1,3,1,1)。
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 的子串數量。
樣例解釋
對於第一個詢問,(3,2,1,3)\approx(2,3,1,3)(3,2,1,3)≈(2,3,1,3),(3,2,1,3)\approx(3,1,3,2)(3,2,1,3)≈(3,1,3,2);
對於第二個詢問,(1,3)\approx(3,1)(1,3)≈(3,1),(1,3)\approx(1,3)(1,3)≈(1,3);
對於第三個詢問,(3,2)\approx(2,3)(3,2)≈(2,3),(3,2)\approx(3,2)(3,2)≈(3,2)。
樣例輸入
5 2 3 1 3 2 3 4 3 2 1 3 2 1 3 2 3 2
樣例輸出
2 2 2
提交運行錯誤。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 7 8 using namespace std; 9 10 int n; 11 int s[50005]; 12 int scou[10005][1200]={0}; 13 int m; 14 int k; 15 int kk[505][50005]; 16 int kkcou[505][1200]={0}; 17 long long sum1=0; 18 long long sum2=0; 19 int ans=0; 20 int ccc=0; 21 22 23 int main() 24 { 25 scanf("%d",&n); 26 for(int i=0;i<n;i++){ 27 //printf("--%d--",i); 28 scanf("%d",&s[i]); 29 } 30 scanf("%d",&m); 31 for(int i=0;i<m;i++){ 32 scanf("%d",&k); 33 for(int j=0;j<k;j++){ 34 scanf("%d",&kk[i][j]); 35 //printf("--%d--",j); 36 kkcou[i][kk[i][j]%1000]++; 37 } 38 sum1=0; 39 ans=0; 40 for(int l=0;l<=999;l++){ 41 sum1+=kkcou[i][l]*l; 42 } 43 for(int mm=k-1;mm<n;mm++){ 44 ccc++; 45 for(int nn=mm-k+1;nn<=mm;nn++){ 46 scou[ccc][s[nn]%1000]++; 47 } 48 sum2=0; 49 for(int o=0;o<=999;o++){ 50 sum2+=scou[ccc][o]*o; 51 } 52 if(sum1==sum2){ 53 ans++; 54 } 55 } 56 printf("%d\n",ans); 57 } 58 return 0; 59 }
UCloud 的安全秘鑰 (計蒜客初賽第五場)(待解決)