【bzoj 2434】【codevs 1946】[Noi2011]阿貍的打字機(AC自動機)

2434: [Noi2011]阿貍的打字機

Time Limit:?10 Sec??Memory Limit:?256 MB
Submit:?2477??Solved:?1382
[Submit][Status][Discuss]

Description

?阿貍喜歡收藏各種稀奇古怪的東西,最近他淘到一臺老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文字母和'B'、'P'兩個字母。

經阿貍研究發現,這個打字機是這樣工作的:

l 輸入小寫字母,打字機的一個凹槽中會加入這個字母(這個字母加在凹槽的最后)。

l 按一下印有'B'的按鍵,打字機凹槽中最后一個字母會消失。

l 按一下印有'P'的按鍵,打字機會在紙上打印出凹槽中現有的所有字母并換行,但凹槽中的字母不會消失。

例如,阿貍輸入aPaPBbP,紙上被打印的字符如下:

a

aa

ab

我們把紙上打印出來的字符串從1開始順序編號,一直到n。打字機有一個非常有趣的功能,在打字機中暗藏一個帶數字的小鍵盤,在小鍵盤上輸入兩個數(x,y)(其中1≤x,y≤n),打字機會顯示第x個打印的字符串在第y個打印的字符串中出現了多少次。

阿貍發現了這個功能以后很興奮,他想寫個程序完成同樣的功能,你能幫助他么?

Input

?輸入的第一行包含一個字符串,按阿貍的輸入順序給出所有阿貍輸入的字符。

第二行包含一個整數m,表示詢問個數。

接下來m行描述所有由小鍵盤輸入的詢問。其中第i行包含兩個整數x, y,表示第i個詢問為(x, y)。

Output

?輸出m行,其中第i行包含一個整數,表示第i個詢問的答案。

Sample Input

aPaPBbP

3

1 2

1 3

2 3

Sample Output

2

1

0

HINT

?1<=N<=10^5


1<=M<=10^5

輸入總長<=10^5

Source

Trie

[Submit][Status][Discuss]

【題解】【AC自動機+樹狀數組

【首先將整個大串建trie樹(P、B不能算進去,遇到要特判,遇到P要將記錄每個單詞的數組更新;遇到B要記錄當前點的父節點,以備后面刪除時往回跳),再建fail樹,根據fail樹神奇的特性,將查詢自動機上root-y的每一個結點,沿著fail指針是否會走到x的結尾點,變為查詢自動機上root-y的所有結點中,有多少個在x的子樹中。按照fail樹跑一遍dfs序。 ?然后將詢問離線,按y排序,每次走到一個等于y的位置就查詢,用樹狀數組維護】


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[100010];
struct question{int num,x,y;
}ask[100010];
int nxt[100010][30],fail[100010],fa[100010],record[100010],num,sz;
int a[200010],next[200010],p[100010],tot;
int in[100010],out[100010],tp;
int tree[200010],ans[100010];
int m,len,cnt;inline int tmp(question a,question b)
{return a.y<b.y;
}
inline void add(int x,int y)
{++tot; next[tot]=p[x]; a[tot]=y; p[x]=tot;++tot; next[tot]=p[y]; a[tot]=x; p[y]=tot;
}void dfs(int now,int father)
{in[now]=++tp;int u=p[now];while (u!=0){int v=a[u];if (v!=father) dfs(v,now);u=next[u];}out[now]=tp;return;
}inline void trie()
{int now=0;for (int i=0;i<len;++i){if (s[i]>='a'&&s[i]<='z'){int x=s[i]-'a';if (!nxt[now][x]) nxt[now][x]=++sz;fa[nxt[now][x]]=now;now=nxt[now][x];}if (s[i]=='P') record[++num]=now;if (s[i]=='B') now=fa[now];}
}
inline void make_fail()
{queue<int>que;for (int i=0;i<26;++i)if (nxt[0][i]) add(0,nxt[0][i]),que.push(nxt[0][i]);while (!que.empty()){int now=que.front(); que.pop();for (int i=0;i<26;++i){int ch=nxt[now][i];if (!ch){nxt[now][i]=nxt[fail[now]][i]; continue;}int x=nxt[now][i];fail[x]=nxt[fail[now]][i];add(x,fail[x]);que.push(x);}}
}inline void init(int x,int val)
{for (int i=x;i<=tp;i+=i&(-i))tree[i]+=val;
}
inline int ask1(int x)
{int sum=0;for (int i=x;i>=1;i-=i&(-i))sum+=tree[i];return sum;
}
int main()
{int i,now,k;scanf("%s",s);len=strlen(s);trie();make_fail();dfs(0,-1);scanf("%d",&m);for (i=1;i<=m;++i)scanf("%d%d",&ask[i].x,&ask[i].y),ask[i].num=i;sort(ask+1,ask+m+1,tmp);now=0;k=1;for (i=0;i<len;++i){if (s[i]>='a'&&s[i]<='z'){int x=s[i]-'a';now=nxt[now][x];init(in[now],1);}if (s[i]=='B'){init(in[now],-1);now=fa[now];}if (s[i]=='P'){++cnt;if (cnt==ask[k].y)for (int j=k;ask[j].y==cnt;++j){int ans1=ask1(in[record[ask[j].x]]-1);int ans2=ask1(out[record[ask[j].x]]);ans[ask[j].num]=ans2-ans1;k=j+1;}}}for (i=1;i<=m;++i)printf("%d\n",ans[i]);return 0;
}


轉載于:https://www.cnblogs.com/lris-searching/p/9402977.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457001.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457001.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457001.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android加法服務類,iOS越來越像Android:蘋果簡單做加法遠離精致

原標題&#xff1a;iOS越來越像Android:蘋果簡單做加法遠離精致剛剛結束的WWDC2016的主題演講中&#xff0c;蘋果為我們帶來了最新的iOS 10系統&#xff0c;官方稱本次iOS 10的推出有著多大10項的重要更新&#xff0c;在用戶體驗、界面、Siri、地圖以及音樂方面都有著不少的變化…

JDK源碼學習之Arraylist與LinkedList

ArrayList和LinkedList是我們在開發過程中常用的兩種集合類&#xff0c;本文將從底層源碼實現對其進行簡單介紹。 下圖是Java集合類所涉及的類圖。 一.ArrayList 從上面的集合類圖可以看出&#xff0c;ArrayList實現了List接口。ArrayList是順序的集合容器,容器中可以存放null…

學習記錄4

學習了python基本數據類型&#xff0c;附學習筆記圖及操作圖 轉載于:https://www.cnblogs.com/bgd140206127/p/6549229.html

self 實例對象-代碼詳細解釋

self代表類的實例&#xff0c;而非類哪個對象調用方法&#xff0c;那么該方法中的self就代表那個對象self.__calss__ 代表類名class Person(object):def run(self):print("run")print(self.__class__)p self.__class__("tt",30,10,20)print(p)def eat(sel…

CString之GetBuffer與ReleaseBuffer

我們知道&#xff0c;CString是MFC中提供的方便字符串操作的一個類&#xff0c;非常好使&#xff0c;具有自動動態內存管理功能。 GetBuffer()主要作用是將字符串的緩沖區長度鎖定&#xff1b; ReleaseBuffer()則是解除對緩沖區的鎖定&#xff0c;這樣使得CString對象在以后的代…

mac 編譯android系統,mac 編譯 Android 系統雜記

掛載android分區sudo hdiutil attach ~/android_code/android7.dmg.sparseimage -mountpoint /Volumes/android原放入U盤&#xff1a;echo 188jinghao | sudo -S hdiutil attach ~/android7.dmg.sparseimage -mountpoint /Volumes/android放入機械硬盤sudo hdiutil attach /Vol…

Java開發必須熟悉的Linux命令總結

身為一個Java開發人員&#xff0c;這些常用的Linux命令必須掌握。即使平時開發過程中沒有使用Linux&#xff08;Unix&#xff09;或者mac系統&#xff0c;也需要熟練掌握Linux命令。因為很多服務器上都是Linux系統。所以&#xff0c;要和服務器機器交互&#xff0c;就要通過she…

構析函數

析構函數&#xff1a;__del__() 釋放對象時自動調用 class Person(object):def run(self):print("run")def eat(self,food):print("eat"food)def __init__(self,name,age,height,weight):self.name nameself.height heightself.age ageself.weight …

Java 序列化Serializable詳解(附詳細例子)

Java 序列化Serializable詳解&#xff08;附詳細例子&#xff09; 1、什么是序列化和反序列化Serialization&#xff08;序列化&#xff09;是一種將對象以一連串的字節描述的過程&#xff1b;反序列化deserialization是一種將這些字節重建成一個對象的過程。 2、什么情況下需要…

kettle-實現每個分組的前N的數據

2019獨角獸企業重金招聘Python工程師標準>>> 第一步&#xff1a;創建表及數據&#xff1a; create table uid(uid int, --uidcate varchar(20), --類別price double --金額 ) insert into uid values(123,c1,21); insert into uid values(123,c2,23); insert into u…

重寫__repr__與__str__函數

重寫&#xff1a;將函數重新定義寫一遍__str__():再調用print 打印對象時自動調用&#xff0c;是給用戶用的是一個描述對象的方法__repr__():是給機器用的&#xff0c;在python解釋器里面直接敲對象名再回車調用的方法注意&#xff1a;在沒有str時&#xff0c;且有repr,str re…

linux nexus 使用問題

2019獨角獸企業重金招聘Python工程師標準>>> 問題一&#xff0c;啟動提示設置RUN_AS_USERroot 但是&#xff0c;設置export或 /etc/profile未生效。 **************************************** WARNING - NOT RECOMMENDED TO RUN AS ROOT *************************…

項目回顧-PopupWindow

右上菜單&#xff0c;可以通過 重寫 onCreateOptionsMenu指定 menu&#xff0c; 重寫 onOptionsItemSelected 來響應點擊事件 不過 這個菜單在某些手機上彈出的有點卡頓&#xff0c;而且如果不對主題進行設置&#xff0c;會從actionbar 上直接彈出&#xff0c;而不是下面 如果想…

android listpreference 自定義,Android ListPreference的用法一

xmlns:android"http://schemas.android.com/apk/res/android"android:key"screen_list"android:title"標題"android:summary"說明摘要">< ListPreferenceandroid:key"myListPreference"android:title"標題"…

C語言求最大公約數和最小公倍數的幾種算法

求最小公倍數算法&#xff1a; 最小公倍數兩整數的乘積最大公約數 求最大公約數算法&#xff1a; (1)輾轉相除法 有兩整數a和b&#xff1a; ① a%b得余數c ② 若c0&#xff0c;則b即為兩數的最大公約數 ③ 若c≠0&#xff0c;則ab&#xff0c;bc&#xff0c;再回去執行①…

3月15日云棲精選夜讀:雙管齊下,MaxCompute數據上云與生態

雙管齊下&#xff0c;MaxCompute數據上云與生態 作者&#xff1a;場景研讀 Go語言并發機制初探 作者&#xff1a;邴越 趣拍云短視頻SDK全面升級&#xff0c;簡單易用引開發者點贊 作者&#xff1a;sherry是雪梨 發表在&#xff1a;趣拍云團隊 阿里云機器學習平臺編程模型演…

qt android glsl,基于Qt的OpenGL學習(1)—— Hello Triangle

簡介要學習OpenGL的話&#xff0c;強烈安利這個教程JoeyDeVries的learnopengl&#xff0c;這里是中文翻譯好的版本。教程中使用OpenGL是通過GLFW這個庫&#xff0c;而在Qt中對OpenGL封裝得很好&#xff0c;并且和GUI以及IO相關的處理Qt更便捷&#xff0c;學習起來更輕松。這里就…

解決:Not Found: /favicon.ico

直接說解決辦法&#xff1a; &#xff08;1&#xff09;制作一個 favicon.ico圖標放在<head></head>標簽中 <link rel"shortcut icon" href"xxxxxxxxxx.ico" type"image/x-icon" /> <!--制作的圖標&#xff0c;使用hr…

多態方法調用的解析和分派

方法調用并不等同于方法執行&#xff0c;方法調用階段唯一的任務就是確定被調用方法的版本&#xff08;即調用哪一個方法&#xff09;&#xff0c;暫時還不涉及方法內部的具體運行過程。在程序運行時&#xff0c;進行方法調用是最普遍、最頻繁的操作&#xff0c;Class文件的編譯…

ES6:Set和Map

Set Set:類似數組&#xff0c;但是成員的值都是唯一的&#xff0c;沒有重復。Set本身是一個構造函數&#xff0c;用來生成Set數據結構。他包含的方法&#xff1a;add: 添加某個值&#xff0c;返回Set結構本身。delete: 刪除某個值&#xff0c;返回一個布爾值&#xff0c;表示是…