日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

吐槽: 為啥很多人用AC自動機暴力跳都過了?復雜度真的對么?

做法一: AC自動機+樹狀數組

姓名的問題,中間加個特殊字符連起來即可。

肯定是對點名串建AC自動機(map存兒子),然后第一問就相當于問每個姓名串(以下稱作“關鍵路徑”)經過了多少個點名串(以下稱做“關鍵點”)在fail樹中的子樹中的至少一點,第二問就相當于問你每條關鍵路徑被多少個關鍵點經過了在fail樹的子樹中至少一個點

所以對于每個關鍵路徑在AC自動機上跑,每跑到一個點把它到根的路徑上打上標記(注意每個姓名串要有不同的標記),最后統計標記個數即可。

然后如果暴力跳去更新可過,我不知道復雜度對不對,感覺是錯的。(也許是\(O(n\sqrt n)\)?)

腦子里第一思路是用bitset, 可以在暴力的復雜度基礎上除以\(\omega\), 沒試過

第二思路是線段樹/啟發式合并,沒仔細想

最后看了一波題解: 我們的目標就是讓同一關鍵路徑上的點只被加一次,這樣就可以變或為加,不需要狀壓bitset了。

然后一種好辦法是像虛樹那樣按DFS序排序,相鄰兩個求出LCA,在LCA到根的路徑上-1. 差分樹狀數組維護即可。

時間復雜度\(O(n\log n)\)

易錯點: 注意AC自動機不補成Trie圖,絕對不能再fail[son[u][i]]=son[fail[u]][i]了!(一晚上的慘痛教訓……) 即使是寫板子也要經過腦子!!!!!!!

聽說也可以SA+主席樹?并不會233

代碼

#include<cstdio> #include<cstdlib> #include<cstring> #include<vector> #include<map> #include<algorithm> using namespace std;const int N = 5e4; const int S = 5e4+1; const int SIZ = 1e5; const int LGSIZ = 16; struct Edge {int v,nxt; } e[(SIZ<<1)+3]; int fe[SIZ+3]; vector<int> a[N+3]; vector<int> b[N+3]; vector<int> ky; map<int,int> son[SIZ+3]; int fail[SIZ+3]; int id[N+3]; int tr[SIZ+3]; int que[SIZ+3]; int ansa[N+3],ansb[N+3]; int dfn[SIZ+3]; int fa[SIZ+3][LGSIZ+3]; int sz[SIZ+3]; int dep[SIZ+3]; int num[SIZ+3]; int n,m,siz,en,cnt;void addval(int lrb,int val) {while(lrb<=cnt){tr[lrb] += val;lrb += (lrb&(-lrb));} }int querysum(int rb) {int ret = 0;while(rb>0){ret += tr[rb];rb -= (rb&(-rb));}return ret; }int insertstr(vector<int> str) {int u = 0;for(int i=0; i<str.size(); i++){if(son[u].count(str[i])==0) {siz++; son[u][str[i]] = siz;}u = son[u][str[i]];}num[u]++;return u; }void buildACA() {int head = 1,tail = 0;for(map<int,int>::iterator iter=son[0].begin(); iter!=son[0].end(); iter++){int u = (iter->second);tail++; que[tail] = u; fail[u] = 0;}while(head<=tail){int u = que[head]; head++;for(map<int,int>::iterator iter=son[u].begin(); iter!=son[u].end(); iter++){int v = (iter->second),i = (iter->first);if(v){int uu = fail[u];while(uu && !son[uu].count(i)) {uu = fail[uu];}fail[v] = son[uu][i];tail++; que[tail] = v;}}} }void addedge(int u,int v) {en++; e[en].v = v;e[en].nxt = fe[u]; fe[u] = en; }void dfs(int u) {cnt++; dfn[u] = cnt;sz[u] = 1;for(int i=1; i<=LGSIZ; i++) fa[u][i] = fa[fa[u][i-1]][i-1];for(int i=fe[u]; i; i=e[i].nxt){if(e[i].v==fa[u][0]) continue;fa[e[i].v][0] = u;dep[e[i].v] = dep[u]+1;num[e[i].v] += num[u];dfs(e[i].v);sz[u] += sz[e[i].v];} }int LCA(int u,int v) {if(dep[u]<dep[v]) swap(u,v);int dif = dep[u]-dep[v];for(int i=LGSIZ; i>=0; i--) {if(dif&(1<<i)) {u = fa[u][i];}}if(u==v) return u;for(int i=LGSIZ; i>=0; i--) {if(fa[u][i]!=fa[v][i]) {u = fa[u][i]; v = fa[v][i];}}return fa[u][0]; }bool cmp_dfn(int x,int y) {return dfn[x]<dfn[y];}int main() {scanf("%d%d",&n,&m); siz = 0;for(int i=1; i<=n; i++){int len; scanf("%d",&len); for(int j=1; j<=len; j++) {int x; scanf("%d",&x); a[i].push_back(x);}a[i].push_back(S);scanf("%d",&len); for(int j=1; j<=len; j++) {int x; scanf("%d",&x); a[i].push_back(x);}}for(int i=1; i<=m; i++){int len; scanf("%d",&len); for(int j=1; j<=len; j++) {int x; scanf("%d",&x); b[i].push_back(x);}id[i] = insertstr(b[i]);}buildACA();for(int i=1; i<=siz; i++){addedge(fail[i],i); addedge(i,fail[i]);}cnt = 0; dfs(0);for(int i=1; i<=n; i++){int u = 0; ky.push_back(u);for(int j=0; j<a[i].size(); j++){while(u && !son[u][a[i][j]]) {u = fail[u];}u = son[u][a[i][j]]; if(u) ky.push_back(u);}sort(ky.begin(),ky.end(),cmp_dfn);for(int j=0; j<ky.size(); j++){if(j>0){int lca = LCA(ky[j],ky[j-1]);addval(dfn[lca],-1); ansa[i] -= num[lca];}addval(dfn[ky[j]],1); ansa[i] += num[ky[j]];}ky.clear();}for(int i=1; i<=m; i++){ansb[i] = querysum(dfn[id[i]]+sz[id[i]]-1)-querysum(dfn[id[i]]-1);}for(int i=1; i<=m; i++) printf("%d\n",ansb[i]);for(int i=1; i<=n; i++) printf("%d ",ansa[i]);return 0; }

總結

以上是生活随笔為你收集整理的BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲自拍第二页 | 伊人青青草 | 免费看黄色的网站 | 日本美女视频 | 美女搞黄在线观看 | 九一在线观看免费高清视频 | 精品国产乱子伦一区二区 | 王者后宫yin肉h文催眠 | 国产男女无遮挡猛进猛出 | 久久久久久一 | 特黄特色大片免费播放器使用方法 | 国产99在线观看 | 成人性生交大免费看 | av网址在线免费观看 | 精品视频站长推荐 | 黄色亚洲视频 | 神马久久精品 | 国产精品久久亚洲 | 成人久久久久久 | 免费看黄视频的网站 | 麻豆精品视频免费观看 | 国产精品久久久久久久久久辛辛 | 中文写幕一区二区三区免费观成熟 | 亚洲区久久 | www.麻豆av| 热久久精| 国产精品大屁股白浆一区 | 久久免费在线视频 | 国产丰满大乳奶水在线视频 | 午夜宅男影院 | 亚洲免费色视频 | 九九九九精品 | 国产淫视 | 可以直接看av的网址 | 午夜性激情 | 免费做a爰片77777 | 爱爱三级视频 | h成人在线| 日本一区二区三区免费看 | 69中国xxxxxxxxx69 国产又爽又色 | 欧美色图另类 | 亚洲欧美中文日韩在线v日本 | 欧美性爱视频久久 | 亚洲少妇精品 | 波多野结衣免费看 | 涩涩在线观看 | 天天干天天操av | 欧美极品在线观看 | 69超碰| 12av在线| 豆花av在线| 谁有毛片网站 | 国产精品欧美精品 | 亚洲天堂影院在线观看 | 不卡的av在线 | 久久久久久久久久久99 | 337p粉嫩日本欧洲亚洲大胆 | 国产专区自拍 | 国语一区二区 | 在线观看视频一区 | 婷婷六月综合网 | 韩日成人 | 久久av色| youjizz.com中国| 久久综合影院 | aaa大片十八岁禁止 中文字幕亚洲在线观看 | 另类专区成人 | 女女互慰吃奶互揉调教捆绑 | 丰满圆润老女人hd | 国产精品对白 | 国产综合欧美 | 欧美妞干网| 成年人网站在线观看视频 | 性一交一乱一区二区洋洋av | 777久久久| 91看片免费版| 国产在线第二页 | 五月婷婷一区二区三区 | 96视频在线观看 | 日本久久高清视频 | av资源免费观看 | 天天摸夜夜添狠狠添婷婷 | 国产aⅴ爽av久久久久成人 | 日韩精品在线视频 | av久草| 黄色片视频在线观看 | 国产精品美女久久久久久久 | xxxxx国产| 亚洲校园激情 | 在线激情av | 天天操中文字幕 | 欧美日韩一级黄色片 | 国产精品免费入口 | 在线免费看黄网站 | 无码人妻丰满熟妇区bbbbxxxx | 激情综合五月网 | 国产欧美精品一区二区 | 久久久久18| 国产剧情自拍 |