洛谷P5108 仰望半月的夜空(尾碼數組)

来源:https://www.cnblogs.com/zwfymqz/archive/2019/03/28/10612560.html
-Advertisement-
Play Games

題意 "題目鏈接" Sol warning:下麵這個做法只有95分,本地拍了1w+組都沒找到錯誤我表示十分無能為力 我們考慮每個串的排名去更新答案,顯然排名為$1$的尾碼的首碼一定是當前長度的字典序最小的答案,但不一定是左端點最小的答案,因此還需要用一個數據結構去維護一下所有可行的左端點。然後枚舉所 ...


題意

題目鏈接

Sol

warning:下麵這個做法只有95分,本地拍了1w+組都沒找到錯誤我表示十分無能為力

我們考慮每個串的排名去更新答案,顯然排名為\(1\)的尾碼的首碼一定是當前長度的字典序最小的答案,但不一定是左端點最小的答案,因此還需要用一個數據結構去維護一下所有可行的左端點。然後枚舉所有尾碼更新答案就行了。

#include<bits/stdc++.h> 
using namespace std;
const int MAXN = 2e6 + 10, SS = 6e5 + 10, INF = 1e9 + 10;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int CharSet, N, M, ans[SS];
int s[SS]; char stmp[SS];
int rak[SS], tp[SS], tax[MAXN * 10], sa[SS], height[SS];
void Sort() {
    for(int i = 0; i <= M; i++) tax[i] = 0;
    for(int i = 1; i <= N; i++) tax[rak[i]]++;
    for(int i = 1; i <= M; i++) tax[i] += tax[i - 1];
    //for(int i = N; i >= 1; i--) sa[i] = tp[tax[rak[i]]--];
    for(int i = N; i >= 1; i--) sa[tax[rak[tp[i]]]--] = tp[i];
}
void SuffixArraryBuild() {
    M = CharSet;
    for(int i = 1; i <= N; i++) rak[i] = s[i], tp[i] = i;
    Sort();
    for(int w = 1, p; w < N; w <<= 1, M = p) {
        p = 0;
        for(int i = N - w + 1; i <= N; i++) tp[++p] = i;
        for(int i = 1; i <= N; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
        Sort(); swap(rak, tp);
        rak[sa[1]] = p = 1; 
        for(int i = 2; i <= N; i++) 
            rak[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w] ? p : ++p);
    }
    for(int i = 1, k = 0; i <= N; i++) {
    
        int j = sa[rak[i] - 1];
        if(k) k--;
        while(j && s[i + k] == s[j + k]) k++;//mmp一開始沒寫j.. 
            height[rak[i]] = k;//tag
    }
}
#define ls k << 1
#define rs k << 1 | 1
int mn[MAXN];
void update(int k) {
    mn[k] = min(mn[ls], mn[rs]);
}
void Build(int k, int l, int r) {
    if(l == r) {mn[k] = sa[l]; return ;}
    int mid = l + r >> 1;
    Build(ls, l, mid); Build(rs, mid + 1, r);
    update(k);
}
int IntQuery(int k, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) return mn[k];
    int mid = l + r >> 1;
    if(ql > mid) return IntQuery(rs, mid + 1, r, ql, qr);
    else if(qr <= mid) return IntQuery(ls, l, mid, ql, qr);
    else return min(IntQuery(ls, l, mid, ql, qr), IntQuery(rs, mid + 1, r, ql, qr));
}
int f[MAXN][20];
int Find(int pos, int cur) {//從pos開始的height,第一個 < cur的位置 
    if(height[pos] < cur) return pos - 1;
    for(int i = 19; i >= 1; i--) {
        while(f[pos][i] >= cur && f[pos][i] <= INF && pos + (1 << i) - 1 <= N) 
            pos = pos + (1 << i) - 1;
    }
    return pos;
}

void solve() {
    Build(1, 1, N);
    memset(f, 0x3f, sizeof(f));
    for(int i = 1; i <= N; i++) f[i][0] = height[i];
    for(int j = 1; j <= 19; j++) 
        for(int i = 1; i + (1 << j) - 1<= N; i++) 
            chmin(f[i][j], min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]));
    
    
    int cur = 1;//馬上要找的答案 
    for(int rk = 1; rk <= N; rk++) {
        if((N - sa[rk] + 1) < cur) continue;
        int pos = sa[rk];
        for(int i = pos + cur - 1; i <= N; i++) {
            int j = Find(rk + 1, cur);
            ans[cur++] = IntQuery(1, 1, N, rk, j);
        }
    }
}
signed main() {
    CharSet = read(); N = read();
    if(CharSet == 26) {
        scanf("%s", stmp + 1);
        for(int i = 1; i <= N; i++) s[i] = stmp[i] - 'a';
    }
    else for(int i = 1; i <= N; i++) s[i] = read();
    SuffixArraryBuild();
    solve();
    for(int i = 1; i <= N; i++) cout << ans[i] << ' ';
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、前言 經過一個月來的學習,我從對面向對象一無所知到逐漸入門,圍繞著“多項式求導”,對面向對象的特性進行了探索。 我對面向對象印象最深的兩句話就是“萬物皆對象”和“高內聚、低耦合”,這三次作業也是儘量貫徹了這兩句話。 我們的作業從第一次的僅含冪函數的求導,到第二次包含正餘弦函數,再到最後函數可以嵌 ...
  • 一. 基於度量的程式結構分析 1. 第一次作業 這次作業是我上手的第一個java程式,使用了4個類來實現功能。多項式採用兩個arraylist來存,繫數和冪指數一一對應。 四個類分別為 Poly類,代表表達式; PolyDiff類,代表求導運算; PolyParse類,封裝了格式檢查,encodin ...
  • 前言 好的代碼需要有高內聚、低耦合、易擴展且擴展改動小等特點。說實話,我入行很久之後,才知道這些設計原則的名字,但是我並不覺得陌生,反而有一種理所當然的感覺。這得感謝自學時網路上前輩們推薦的書籍,培養了自己的代碼潔癖,還得感謝轉行後的第一個東家!以下只是我的理解,如有錯誤,請指正。 單一職責原則 顧 ...
  • return語句 return語句用來從一個函數中 返回 即跳出函數。當然也可以從函數中返回一個值。 運行結果 DocStrings Python有一個很奇妙的特性,稱為 文檔字元串 ,它通常被簡稱為 docstrings 。DocStrings是一個重要的工具,由於它幫助你的程式文檔更加簡單易懂, ...
  • 列表[List] 元組(truple) 字典{dict} 生成器(generator) 帶有 yield 的函數在 Python 中被稱之為 generator(生成器) 迭代器 iterator 迭代器是訪問集合元素的一種方式。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代 ...
  • 預設參數 對於參數有時候我們希望他是可選的,前面介紹了函數柯里化,當然還有其他的解決方案。如果不想給某些參數提供值的話,就讓這寫參數使用預設值。在函數定義的時候給參數賦值使用(參數,參數=值......),從而給形參指定預設值。 註意預設參數的值是一個不可變的參數(也就是說預設參數是一個確定的值)。 ...
  • 有時候,我們想要獲取一個對象關聯關係的數量,但是我們不要所有的關聯對象,我們只想要符合規則的那些關聯對象的數量。 ...
  • 爬蟲背景 爬蟲最核心的問題就是解決重覆操作,當一件事情可以重覆的進行的時候,就可以用爬蟲來解決這個問題,今天要實現的一個基本需求是完成“博客園“ 博客的自動評論,其實原理是非常簡單的,提煉一下需求 基本需求 1. 登錄博客園 2. 調用評論介面 3. 返回請求結果 確定流程之後,基本就是找突破口的環 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...