BUAA 533 nanae 是弱小灰(SAM)
轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
題意 :給出一個A串,給出若干B串,問A中有多少個不相同的子串是以某個B串為字尾的。
Dshawn找我出個SAM,為了nanae的生日賽。
無聊的跨專業課,就出了這個個題吧~~~~~
對於SAM來說,解法比較簡單。
首先將A串和B串都反向之後,字尾便為字首,題目轉變為A串中有多少個不相同的子串是以某個B串為字首的。
那麼以A串建立SAM之後,首先預處理一下,對於A中的每一個子串,存在多少個不同的後繼。這就是一個簡單的DAG上的DP。得到的結果其實就是,以當前子串為字首的不同的子串有多少個 (= =這樣說的話,問題就解決了。
遍歷每一個B串,如果A中存在這個子串,那麼就統計一下這個子串有多少個後繼,疊加一下就行了。
這樣明顯有個問題,便是存在重複子串。
大概 就是如果某個結點被統計過,那麼他後繼中的所有結點的後繼,都已經被包括其中。
那麼其中一種處理方法便是,處理完之後,把可達的結點標記一下,然後通過DAG關係,依次處理,而且將所有後繼中的標記撤消。
那麼另外一種處理方法便是,問題的源由在於,B串中某些串是某個串的字首之類的。那麼將B按字典序排序之後,依次處理,如果某個B經過了已經被標記過的結點,那麼直接退出。
AekdyCoin的做法是SA,巨巨真可怕,不過不得不說SA的做法好麻煩,耗時也多。ORZ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define LL long long
using namespace std;
const int N=210005;
struct Node{
char word[105];
bool operator<(const Node n)const{
return strcmp(word,n.word)<0;
}
}a[1005];
struct SAM {
SAM *pre,*son[26];
int f,len;
LL cnt;
}*root,*tail,que[N],*b[N];
char str[N];
int cnt[N];
int tot=0;
int c[N];
int n;
void add(int c,int l){
SAM *p=tail,*np=&que[tot++];
np->len=l;
while(p&&p->son[c]==NULL) p->son[c]=np,p=p->pre;
if(p==NULL) np->pre=root;
else{
SAM *q=p->son[c];
if(p->len+1==q->len) np->pre=q;
else{
SAM *nq=&que[tot++];
*nq=*q;
nq->len=p->len+1;
np->pre=q->pre=nq;
while(p&&p->son[c]==q) p->son[c]=nq,p=p->pre;
}
}
tail=np;
}
LL ans=0;
int main(){
// freopen("1.in","r",stdin);
// freopen("output.txt","w",stdout);
root=tail=&que[tot++];
scanf("%s",str);
int l=strlen(str);
for(int i=0;i<l/2;i++) swap(str[i],str[l-1-i]);
for(int i=0;str[i];i++) add(str[i]-'a',i+1);
for(int i=0;i<tot;i++) c[que[i].len]++;
for(int i=1;i<tot;i++) c[i]+=c[i-1];
for(int i=0;i<tot;i++) b[--c[que[i].len]]=&que[i];
for(int i=0;i<tot;i++) que[i].cnt=1;
for(int i=tot-1;i>=0;i--){
SAM *p=b[i];
for(int j=0;j<26;j++){
if(p->son[j])
p->cnt+=p->son[j]->cnt;
}
}
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",a[i].word);
int l=strlen(a[i].word);
for(int j=0;j<l/2;j++)
swap(a[i].word[j],a[i].word[l-1-j]);
}
sort(a,a+n);
for(int j=0;j<n;j++){
SAM *p=root;
bool flag=true;
for(int i=0;a[j].word[i]&&flag;i++){
int s=a[j].word[i]-'a';
if(p->son[s]==NULL) flag=false;
else{
if(p->son[s]->f) flag=false;
p=p->son[s];
}
}
if(flag){
ans+=p->cnt;
p->f=1;
}
}
printf("%lld\n",ans);
return 0;
}
相關文章
- SAM & 廣義 SAM
- sam初識+sam詳解
- to:sam_javaJava
- 廣義 SAM
- 「BUAA OO Pre」 Pre 2總結回顧概覽
- 退款灰產,是誰在吸玩家和遊戲公司的血?遊戲
- 四問灰鴿子工作室:你不是病毒是什麼?
- SAM基因晶片分析軟體晶片
- yang-xi-jie-mi-sam
- 微軟前僱員曝公司內幕 蓋茨“獨裁”欺凌弱小微軟
- 尤拉計劃533題:卡邁克爾函式函式
- Oracle 11G OCP 1Z0-053 533Oracle
- SAM已經Out了!TS-SAM:適應下游任務的分割一切!
- [BUAA2021軟工助教]案例分析作業總結軟工
- 昨天網站都變灰了,你知道是怎麼做的麼?網站
- 網路黑灰產業已近千億 個人資訊洩露是源頭產業
- iOS圖片變灰iOS
- EXCEL選單變灰Excel
- Sam Altman的成功學|升維指南
- 【筆記】字尾自動機 SAM筆記
- SAM視覺大模型的finetune視覺大模型
- hdu7462-字串【SAM,二分】字串
- 按鈕置灰的思考
- VSCode #ifdef 變灰VSCode
- RocketMq灰皮書(三)------MQ使用MQ
- 灰哥的二叉樹二叉樹
- css3圖片變灰CSSS3
- sam9260 adc 標頭檔案
- 比對檔案sam檔案的解讀
- 無需訓練即可大幅提升SAM 2!開源的SAM2Long來了,港中文、上海AI Lab出品AI
- 比隱私濫用更可怕的,是AI攝像頭的黑灰產之困AI
- 網路安全中什麼是白帽、黑帽、灰帽駭客?有什麼區別?
- HG533路由器分析教程之三:資料流跟蹤路由器
- 黑灰產如何薅色情APP羊毛?揭秘助力黑灰產偽造新裝置的“它”APP
- 使用pwdump 匯出本地windows SAM雜湊並破解Windows
- Meta AI 開源萬物可分割 AI 模型(SAM)AI模型
- SAM9G45之USB學習筆記筆記
- python灰帽子講的什麼Python