bzoj2746: [HEOI2012]旅行问题
2746: [HEOI2012]旅行問題
Time Limit:?30 Sec??Memory Limit:?256 MBSubmit:?926??Solved:?295
[Submit][Status][Discuss]
Description
yz是Z國的領導人,他規定每個地區的名字只能為26個小寫拉丁字母的一個。由于地 區數有可能超過26個,便產生了一個問題,如何辨別名字相同的地區?于是yz規定,一個 地區的描述必須包含它的所有上級,且上級按次序排列。于是,一個地區的描述是一個字符 串。比如說,一個地區的名字為c,它的上級為b,b的上級為a,a沒有上級,那么這個地 區就描述為abc。顯然,這個描述同時包含了c的上級b和b的上級a的描述,分別為ab和a。 值得注意的是,每個地區最多有一個上級,同一上級的地區之間名字不同,沒有上級的 地區之間名字不同。現在,yz對外公布了n個地區的描述,這些描述中包含了Z國所有地區的描述,并讓 你處理來訪者的旅行問題?,F有m對人訪問這個國家,對于每對人,第一個人喜歡第i個描述中的第j個地區,設 這個地區描述為s1,第二個人喜歡第k個描述中的第l個地區,設這個地區描述為s2。他們為了統一行程,決定訪問描述為s的地區(顯然他們只關心地區的名字,并非是地區本身), 設s的長度為t,s需要滿足以下條件:?
1:t<=j, t<=l;?
1:s[1..t] = s1[j-t+1 … j], s[1..t] = s2[l-t+1 … l];(即s為s1中1到k位 與s2中1到l位的公共后綴)?
2:t最大化。?
為了不使輸出過大,你只需把這個字符串按照如下生成的26進制數轉成10進制后mod 1000000007后輸出:?
a->0?
b->1?
.?
.?
.?
z->25?
比如地區cab被編碼成2 *??? 26? + 0 * 26? + 1 * 26? = 1353。?
Input
第一行給定一個整數n?
第2…n+1行:每i+1行給定一個字符串a[i],表示第i個描述。?
接下來一行一個整數m?
接下來m行:每行給定四個整數i,j,k,l,字母含義與題目描述一致。?
Output
共m行,每行一個整數,表示答案字符串的編碼。?
Sample Input
2aabb babb
2
1 3 2 3
1 4 2 4
Sample Output
11
【樣例說明】
詢問1中的公共后綴有ab和b,但是沒有ab這個地區,只有b地區,所以只能選擇b這個 地區;
詢問2中的公共后綴有abb、bb和b,但是沒有abb和bb這兩個地區,只有b地區,所以 只能選擇b這個地區。
HINT
?
【數據范圍】
?設這個國家地區總數數為tot(注意:輸入的字符串總長度可能超過tot!) 對于30%的數據,滿足tot,m,n<=100;?
對于50%的數據,滿足tot,m,n<=1000;?
對于80%的數據,滿足tot,m,n<=100000;?
對于100%的數據,滿足tot,m,n<=1000000;?
保證輸入文件不超過20MB。?
?
題解
? ?這題題意實在是……不評論
? ?簡化一下就是說現在有一個字符串的集合,每次詢問兩個字符串i,k,求第i個字符串長度為j的前綴(si[1..j])和第k個字符串長度為l的前綴(sk[1..l])的最長公共后綴,而且這個后綴必須是字符串集合中某個字符串的前綴(其實就是方便你直接在ac自動機上找答案)
? ? 然后……知道fail樹的都應該知道怎么做了……直接在fail樹上找lca……因為fail樹上某個節點的祖先(我們假設節點就代表根到它路徑形成的字符串)一定是這個節點的后綴,然后也滿足是字符串集合中某個字符串前綴的條件……兩個點共同的不就是lca嘛QWQ
? ? 一開始mle了……沒有1A啊QAQ
?
1 /************************************************************** 2 Problem: 2746 3 User: 1090900715 4 Language: Pascal 5 Result: Accepted 6 Time:8036 ms 7 Memory:256772 kb 8 ****************************************************************/ 9 10 program j01; 11 const maxn=1 shl 20;mo=1000000007;base=26; 12 var t:array[0..maxn]of record son:array['a'..'z']of longint;end; 13 ps:array[0..maxn*8]of longint; 14 st:array[0..maxn]of longint; 15 fa:array[0..maxn,0..21]of longint; 16 dep:array[0..maxn]of longint; 17 l,bin:array[0..maxn]of longint; 18 sum:array[0..maxn]of int64; 19 n,m,x1,x2,y1,y2,i,cnt,tot:longint; 20 s:ansistring; 21 ch:char; 22 23 procedure swap(var a,b:longint); 24 var c:longint; 25 begin 26 c:=a;a:=b;b:=c; 27 end; 28 29 procedure insert(x:longint); 30 var now,i:longint; 31 begin 32 now:=1;st[x]:=tot; 33 for i:=1 to length(s) do 34 begin 35 if t[now].son[s[i]]=0 then 36 begin 37 inc(cnt);t[now].son[s[i]]:=cnt; 38 sum[cnt]:=(sum[now]*26+(ord(s[i])-ord('a')))mod mo; 39 end; 40 now:=t[now].son[s[i]]; 41 inc(tot);ps[tot]:=now; 42 end; 43 end; 44 45 procedure build; 46 var i,j,h,tail,k:longint;ch:char; 47 begin 48 fa[1,0]:=0;dep[1]:=0;h:=0;tail:=1; 49 l[1]:=1; 50 while h<>tail do 51 begin 52 inc(h);i:=l[h]; 53 for ch:='a' to 'z' do 54 begin 55 j:=t[i].son[ch]; 56 if j=0 then 57 begin 58 t[i].son[ch]:=t[fa[i,0]].son[ch];continue; 59 end; 60 fa[j,0]:=t[fa[i,0]].son[ch]; 61 dep[j]:=dep[fa[j,0]]+1; 62 for k:=1 to bin[dep[j]] do fa[j,k]:=fa[fa[j,k-1],k-1]; 63 inc(tail);l[tail]:=j; 64 end; 65 end; 66 end; 67 68 function lca(u,v:longint):longint; 69 var d,i:longint; 70 begin 71 if u=v then exit(u); 72 if dep[u]<dep[v] then swap(u,v); 73 d:=dep[u]-dep[v]; 74 for i:=0 to bin[d] do 75 if d and(1 shl i)>0 then u:=fa[u,i]; 76 for i:=bin[dep[v]] downto 0 do 77 if fa[u,i]<>fa[v,i] then 78 begin 79 u:=fa[u,i];v:=fa[v,i]; 80 end; 81 if u=v then exit(u) else exit(fa[u,0]); 82 end; 83 84 begin 85 for ch:='a' to 'z' do t[0].son[ch]:=1;cnt:=1;tot:=0;sum[1]:=0; 86 readln(n); 87 for i:=1 to n do 88 begin 89 readln(s);insert(i); 90 end; 91 bin[1]:=0; 92 for i:=2 to cnt do 93 if i and(i-1)=0 then bin[i]:=bin[i-1]+1 else bin[i]:=bin[i-1]; 94 build; 95 readln(m); 96 for i:=1 to m do 97 begin 98 readln(x1,x2,y1,y2); 99 writeln(sum[lca(ps[st[x1]+x2],ps[st[y1]+y2])]); 100 end; 101 end. 102 View Code?
?
?
轉載于:https://www.cnblogs.com/oldjang/p/6496806.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的bzoj2746: [HEOI2012]旅行问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU D Tree [点分治]
- 下一篇: 《深入理解JAVA虚拟机》——学习笔记