1. 程式人生 > >【BZOJ4516】【SDOI2016】生成魔咒(SAM)

【BZOJ4516】【SDOI2016】生成魔咒(SAM)

Description

魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1、2 拼湊起來形成一個魔咒串 [1,2]。
一個魔咒串 S 的非空字串被稱為魔咒串 S 的生成魔咒。
例如 S=[1,2,1] 時,它的生成魔咒有 [1]、[2]、[1,2]、[2,1]、[1,2,1] 五種。S=[1,1,1] 時,它的生成魔咒有 [1]、[1,1]、[1,1,1] 三種。最初 S 為空串。共進行 n 次操作,每次操作是在 S 的結尾加入一個魔咒字元。每次操作後都需要求出,當前的魔咒串 S 共有多少種生成魔咒。

Solution

算是SAM模板題吧。。
每次新加入一個數字(實質是一個字首)後,貢獻為

lenilenfai(fai為字尾鏈)

額,輸入的數有點大,ch[u][c]std::map<int,int>或者__gnu_pbds::cc_hash_table都可以。ljBZOJ似乎用不了unordered_map吧。

Source

/************************************************
 * Au: Hany01
 * Date: Apr 1st, 2018
 * Prob: [BZOJ4516][SDOI2016] 生成魔咒
 * Email: [email protected]
************************************************/
#include<bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/hash_policy.hpp> using namespace std; using namespace __gnu_pbds; typedef long long LL; typedef pair<int, int> PII; #define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout) #define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i) #define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i) #define Set(a, b) memset(a, b, sizeof(a)) #define Cpy(a, b) memcpy(a, b, sizeof(a)) #define x first #define y second #define pb(a) push_back(a) #define mp(a, b) make_pair(a, b) #define ALL(a) (a).begin(), (a).end() #define SZ(a) ((int)(a).size()) #define INF (0x3f3f3f3f) #define INF1 (2139062143) #define Mod (1000000007) #define debug(...) fprintf(stderr, __VA_ARGS__) #define y1 wozenmezhemecaia template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; } template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; } inline int read() { register int _, __; register char c_; for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1; for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48); return _ * __; } const int maxn = 100005; int fa[maxn << 1], len[maxn << 1], tot = 1, las = 1; cc_hash_table<int, int> ch[maxn << 1]; inline int extend(int c) { register int np = ++ tot, p = las; las = np, len[np] = len[p] + 1; while (p && !ch[p][c]) ch[p][c] = np, p = fa[p]; if (!p) fa[np] = 1; else { register int q = ch[p][c]; if (len[q] == len[p] + 1) fa[np] = q; else { register int nq = ++ tot; fa[nq] = fa[q], ch[nq] = ch[q], len[nq] = len[p] + 1; fa[np] = fa[q] = nq; while (p && ch[p][c] == q) ch[p][c] = nq, p = fa[p]; } } return len[np] - len[fa[np]]; } int main() { #ifdef hany01 File("bzoj4516"); #endif static int n = read(); static LL Ans = 0; For(i, 1, n) { register int ne = read(); printf("%lld\n", Ans += extend(ne)); } return 0; } //今宵酒醒何處?楊柳岸,曉風殘月。 // -- 柳永《雨霖鈴·寒蟬悽切》

相關推薦

BZOJ4516SDOI2016生成SAM

Description 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1、2 拼湊起來形成一個魔咒串 [1,2]。 一個魔咒串 S 的非空字串被稱為魔咒串 S 的生成魔咒。

洛谷4070 [SDOI2016]生成SAM

show 就是 代碼實現 sum 在線 字符串 什麽 pcs problem 傳送門 洛谷 Solution 考慮要求的是什麽,前綴的本質不同的字符串個數? 如果只要求一個串那麽顯然答案是\(\sum_{i=1}^{tot}len[i]-len[fa[i]]\)(實際上這個

BZOJ4516生成字尾自動機

題面 BZOJ Description 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1、2 拼湊起來形成一個魔咒串 [1,2]。 一個魔咒串 S 的非空字串被稱為魔咒串 S 的生成魔咒。 例如 S=[1,2,1] 時,它的

[BZOJ4516][Sdoi2016]生成字尾陣列+set/字尾自動機

解法一:字尾陣列+set 國家集訓隊論文《字尾陣列——處理字串的有力工具 》中介紹過,長度為nn的字串不同的非空子串個數,等於 ∑i=1n(n−sa[i]+1−height[i])∑i=1n(n−sa[i]+1−height[i]) 由於∑ni=1sa[

[BZOJ4516][Sdoi2016]生成字尾陣列+連結串列||字尾自動機

題目描述 傳送門 題解 題意實際上是求對於每一個字首本質不同的子串個數 那麼可以轉化為對於每一個字首只求包含最後一個點的和前面不重複的子串個數,然後將答案累加 把串反過來建字尾陣列 然後

[BZOJ4516][Sdoi2016]生成字尾陣列+連結串列

題目 傳送門 題解 這道題還是比較好的; 要求出每一個字首本質不同的字尾的個數,那麼我們可以把原序列倒過來,然後實際上就是對於每一個字尾求與其它字尾不重複的字首個數,也即是字尾長度減去height值; 求出某一個字尾對答案的貢獻之後,他不應該停留在

LibreOJ #2033. 「SDOI2016生成

col clas uil str stat swap pri pre evel 二次聯通門 : LibreOJ #2033. 「SDOI2016」生成魔咒 /* LibreOJ #2033. 「SDOI2016」生成魔咒 調了整整一天啊

[SDOI2016]生成後綴自動機

algo 等等 clu long 個數 字符串 一個 sign ++ 看一眼題。本質不同的字串數。 嘴角微微上揚。 每一次加一個數輸出一個答案。 笑容漸漸消失。 等等,\(SAM\)好像也可以求本質不同的字串。 設當前字符串用\(x\)表示,每次插入完成後\(ans\)加上

SDOI2016BZOJ4516生成

【題目連結】 【前置技能】 字尾樹 【題解】 要求支援向字串後加一個字元,詢問字串中本質不同的子串的個數。 考慮建立原串的反串的字尾樹,新出現的反串的字尾對於答案的貢獻為dep[pos]−dep[fa[pos]]dep[pos] - dep[fa[pos

bzoj4516SDOI2016生成

4516: [Sdoi2016]生成魔咒 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 376  Solved: 232 [Submit][Sta

字尾自動機 Sdoi2016生成 bzoj4516

題目大意: 給你n個數,每個數代表一個不同的字元。 初始為空串,每次在裡面插入一個字元,並且詢問本質不同的子串的個數。 題目分析:(字尾自動機) 字尾自動機想要表示所有的字尾以及字尾的字首,就會

SDOI2016bzoj4516 生成解法一

每次在SAM中加入一個字元,維護每個點的vali−valfaili即可。 因為字符集很大,離散化以後也開不下,可以用map存轉移。 #include<cstdio> #include&l

4516. [SDOI2016]生成後綴自動機

sdoi ace 字串 right 三種 esp oid n) 自動 Description 魔咒串由許多魔咒字符組成,魔咒字符可以用數字表示。例如可以將魔咒字符 1、2 拼湊起來形成一個魔咒串 [1,2]。 一個魔咒串 S 的非空字串被稱為魔咒串 S 的生成魔咒。

文文殿下 [SDOI2016]生成

字符集大小為1e9.............使用 map 吧 統計本質不同的子串個數是SAM的經典應用之一 本質不同的子串個數其實就是\(\sum max(x)-min(x)+1\) 所以我們新建結點 \(np\) 時統計它的答案即可 根據我們統計的式子,顯然新建節點\(nq\)的時候,不會對答案造成

[SDOI2016]生成

ans char oid -h 排名 new ring 動態 答案 這是一道\(SA\)的練手好題 建議做之前先去做一下2408 之後你就肯定會做這道題了 首先上面那道題的答案就是 \[\sum_{i=1}^nn+1-sa[i]-het[i]\] 就是對於每一個後綴求出其能

LG4070[SDOI2016]生成

構建 char break oid www. www org tchar ans 【LG4070】[SDOI2016]生成魔咒 題面 洛谷 題解 如果我們不用在線輸的話,那麽答案就是對於所有狀態\(i\) \[ \sum (i.len-i.fa.len) \] 現在我們需要

Selenium2+python自動化54-unittest生成測試報告HTMLTestRunner轉載

logs mage 部分 art 測試結果 函數返回 top default 執行 本篇轉自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/unittest/ 前言 批量執行完用例後,生成的測試報告是文本形式的,不夠直

基礎隨機數生成--C++原始碼VS2015

#include <iostream> #include <ctime> #include <vector> using namespace std; void Print(const vector<int> &vec

SSH進階之路Struts + Spring + Hibernate 進階開端

height 一段 ioc 效率 陽光大道 面向對象的思想 text ase 們的 Long Long ago。就聽說過SSH。起初還以為是一個東東,詳細內容更是不詳,總認為高端大氣上檔次,經過學習之後才發現,不不過高大上,更是低調奢華有內涵,經過一段時間的

ShiroApache Shiro架構之身份認證Authentication

trac pretty asm 安全保障 軟件測試 釋放 model tac 讀取配置文件 Shiro系列文章: 【Shiro】Apache Shiro架構之權限認證(Authorization) 【Shiro】Apache Shiro架構之集成web