題意:給出n
nn個字串,求它們所有不同子串的數字和(取模)。
題解:字尾自動機
先將n
nn個字串拼接,然後建立sam,跑拓撲。
這裡可以在串之間新增無效字元,也可以將las
tlast
last
指向r oo
troot
root
,學到了學到了。
在遍歷的時候,遇到top
sam[
i]
topsam[i]
topsam
[i]若為初始狀態,則j
jj從1開始。
c nt
[i
]cnt[i]
cnt[i]
:從初始狀態到狀態i
ii中的所有不含分隔符以及前導0的子串數量。
cnt[topsam[i]->next[j]->id] += cnt[topsam[i]->id];
s um
[i
]sum[i]
sum[i]
:從初始狀態到狀態i
ii的所有合法路徑形成的數字之和。
sum[topsam[i]->next[j]->id] += sum[topsam[i]->id] * 10 + j * cnt[topsam[i]->id];
然後累加。
ans += sum[topsam[i]->id];
#define _crt_secure_no_warnings
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using
namespace std;
const
int char =26;
const
int maxn =
200020
;struct sam_node
sam_node
(int _len)};
sam_node sam_node[maxn *2]
,* sam_root,
* sam_last,
* topsam[maxn *2]
;int sam_size, topcnt[maxn]
;sam_node*
newsam_node
(int len)
sam_node*
newsam_node
(sam_node* p)
void
sam_init()
void
sam_add
(int x)
sam_node* q = p-
>next[x];if
(q->len == p-
>len +1)
sam_node* nq =
newsam_node
(q);
nq->len = p-
>len +1;
q->fa = np-
>fa = nq;
for(
; p && p-
>next[x]
== q; p = p-
>fa) p-
>next[x]
= nq;
}void
sam_build
(char
* s)
void
topo()
char s[maxn]
;int n, sum[maxn]
, cnt[maxn]
;int
main()
topo()
;memset
(sum,0,
sizeof
(sum));
memset
(cnt,0,
sizeof
(cnt));
cnt[0]
=1;int ans =0;
for(
int i =
0; i <= sam_size; i++)}
ans +
= sum[topsam[i]
->id]
; ans %
=2012;}
printf
("%d\n"
, ans);}
return0;
}
AC之回溯演算法UVA167
經典的八皇后問題,此題要求和。用的c c,d陣列判斷對角線,a 0 判斷此列是否有皇后,只有滿足三個條件才能算找到,a 0 判斷此行皇后在哪 核心 中 分別判斷1.如果沒找到 y 9 回溯 2.在最後一行找到了,儲存記錄資料,回溯 3.普通找到,繼續執行 缺點就是作為萌新 冗雜。include in...
UVA 167 蘇丹的繼承者
是時候對於dfs搜尋做乙個簡單的小結了 八皇后問題 解法一 include include include include include include include include include include include include include include include ...
167 兩數之和II (Two SumII)
暴力法兩次雜湊表 一次雜湊表 和1.兩數之和 leetcode 1.兩數之和 csdn不同之處在於,本題附加了有序的特殊限定。同樣可以借助於暴力法在時間複雜度o n 2 o left n right o n2 和空間o 1 o 1 o 1 解決。和雜湊表時間o n o left n right o ...