2746 HEOI2012 旅行問題

2021-07-10 07:10:31 字數 2720 閱讀 4113

time limit: 30 sec  

memory limit: 256 mb

submit: 718  

solved: 243 [

submit][

status][

discuss]

yz是z國的領導人,他規定每個地區的名字只能為26個小寫拉丁字母的乙個。由於地 區數有可能超過26個,便產生了乙個問題,如何辨別名字相同的地區?於是yz規定,乙個 地區的描述必須包含它的所有上級,且上級按次序排列。於是,乙個地區的描述是乙個字元 串。比如說,乙個地區的名字為c,它的上級為b,b的上級為a,a沒有上級,那麼這個地 區就描述為abc。顯然,這個描述同時包含了c的上級b和b的上級a的描述,分別為ab和a。 值得注意的是,每個地區最多有乙個上級,同一上級的地區之間名字不同,沒有上級的 地區之間名字不同。現在,yz對外公布了n個地區的描述,這些描述中包含了z國所有地區的描述,並讓 你處理來訪者的旅行問題。現有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。 

第一行給定乙個整數n 

第2…n+1行:每i+1行給定乙個字串a[i],表示第i個描述。 

接下來一行乙個整數m 

接下來m行:每行給定四個整數i,j,k,l,字母含義與題目描述一致。 

共m行,每行乙個整數,表示答案字串的編碼。  2

aabb babb

2 1 3 2 3

1 4 2 411

【樣例說明】

詢問1中的公共字尾有ab和b,但是沒有ab這個地區,只有b地區,所以只能選擇b這個 地區;

詢問2中的公共字尾有abb、bb和b,但是沒有abb和bb這兩個地區,只有b地區,所以 只能選擇b這個地區。

【資料範圍】

設這個國家地區總數數為tot(注意:輸入的字串總長度可能超過tot!) 對於30%的資料,滿足tot,m,n<=100; 

對於50%的資料,滿足tot,m,n<=1000; 

對於80%的資料,滿足tot,m,n<=100000; 

對於100%的資料,滿足tot,m,n<=1000000; 

保證輸入檔案不超過20mb。  [

submit][

status][

discuss]

ac自動機。。

把所有串串扔進自動機構造fail tree

每次詢問輸出對應節點的lca就是

6666666666666666666666666666666

一開始陣列開太大了sad。。。

因為是用後悔邊建的樹,所以深度要在遞推完f陣列後才能算(第二次寫的時候不幸出錯)

#include#include#include#include#includeusing namespace std;

const int maxn = 1e6 + 10;

typedef long long ll;

const ll mo = 1000000007ll;

int n,m,cnt = 0,ch[maxn][26],f[maxn][20],l[maxn];

ll ans[maxn];

char c[maxn];

vector pos[maxn];

queue q;

int lca(int a,int b)

return ans[f[a][0]];

}int main()

x = ch[x][po];

pos[i].push_back(x);

} }for (int i = 0; i < 26; i++)

if (ch[0][i])

while (!q.empty())

int v = f[k][0];

while (v && !ch[v][i]) v = f[v][0];

l[u] = l[ch[v][i]] + 1;

f[u][0] = ch[v][i];

q.push(u);

} }for (int j = 1; j < 20; j++)

for (int i = 1; i <= cnt; i++)

f[i][j] = f[f[i][j-1]][j-1];

cin >> m;

while (m--)

return 0;

}

百練2746 約瑟夫問題

總時間限制 1000ms 記憶體限制 65536kb 描述 約瑟夫問題 有 只猴子,按順時針方向圍成一圈選大王 編號從 到 從第 號開始報數,一直數到 數到 的猴子退出圈外,剩下的猴子再接著從1開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王,程式設計求輸入 後,輸出最後猴王的編號。輸入...

poj2746約瑟夫問題

2746 約瑟夫問題 檢視 提交 統計 提示 提問 總時間限制 1000ms 記憶體限制 65536kb 描述約瑟夫問題 有 只猴子,按順時針方向圍成一圈選大王 編號從 到 從第 號開始報數,一直數到 數到 的猴子退出圈外,剩下的猴子再接著從1開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是...

Bailian2746 約瑟夫問題

描述 約瑟夫問題 有 只猴子,按順時針方向圍成一圈選大王 編號從 到 從第 號開始報數,一直數到 數到 的猴子退出圈外,剩下的猴子再接著從1開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王,程式設計求輸入 後,輸出最後猴王的編號。輸入每行是用空格分開的兩個整數,第乙個是 n,第二個是 m...