字串問題

2022-08-01 18:45:13 字數 3544 閱讀 5642

題目背景

yazid 和 tiffany 喜歡字串問題。在這裡,我們將給你介紹一些關於字串的基本概念。

對於乙個字串 $s$, 我們定義 $\lvert s\rvert$ 表示 $s$ 的長度。

接著,我們定義該串的子串 $s\left( \right)$ 表示由 $s$ 中從左往右數,第 $l$ 個字元到第 $r$ 個字元依次連線形成的字串,特別地,如果 $l < 1$ 或 $r > \lvert s\rvert$ 或 $l > r$,則 $s\left( \right)$ 表示空串。

我們說兩個字串相等,當且僅當它們的長度相等,且從左至右各位上的字元依次相同。

我們說乙個字串 $t$ 是 $s$ 的**字首**,當且僅當 $s\left( 1,\lvert t\rvert\right)=t$。

兩個字串 $s,t$ 相加 $s+t$ 表示的是在 $s$ 後緊挨著寫下 $t$ 得到的長度為 $\lvert s\rvert+\lvert t\rvert$ 的字串。

題目描述

現有乙個字串 $s$。

tiffany 將從中劃出 $n_a$ 個子串作為 a 類串,第 $i$ 個($1\leq i\leq n_a$)為 $a_i = s\left( la_i, ra_i\right)$。

類似地,yazid 將劃出 $n_b$ 個子串作為 b 類串,第 $i$ 個($1\leq i\leq n_b$)為 $b_i = s\left( lb_i, rb_i\right)$。

現額外給定 $m$ 組支配關係,每組支配關係 $\left( x,y\right)$ 描述了第 $x$ 個 a 類串**支配**第 $y$ 個 b 類串。

求乙個**長度最大**的目標串 $t$,使得存在乙個串 $t$ 的分割 $t=t_1 + t_2 +\dots +t_k$($k\geq 0$)滿足:

- 分割中的每個串 $t_i$ 均為 a 類串:即存在乙個與其相等的 a 類串,不妨假設其為 $t_i = a_$。

- 對於分割中所有相鄰的串 $t_i , t_$($1\leq i < k$),都有存在乙個 $a_$ 支配的 b 類串,使得該 b 類串為 $t_$ 的字首。

方便起見,你只需要輸出這個最大的長度即可。

特別地,如果存在無限長的目標串(即對於任意乙個正整數 $n$,都存在乙個滿足限制的長度超過 $n$ 的串),請輸出 $-1$。

solution

首先考慮暴力建圖:a向支配的b連,b向字首包含它的連。然後跑拓撲序dp。 40『(我這咋只有20)

用sam優化:用反串建,則x為x的後代的字首。

那麼可以把par樹連起來,然後支配邊照常連,邊數2n 。80』

不能滿分是因為如果b[i]>a[i],連邊後可能兩個b被壓在了同乙個節點,但是乙個可以被支配,乙個不行。

把乙個sam節點上的所有串按長度排序,從長度小的開始連,每次當前點與它的上乙個b點。相當於串了起來。

這樣子如果a能支配某乙個b1,那麼他只會連到這個b1,然後再間接的連到乙個比b1長的b2...

而如果b2是某個串的字首,那麼b1也是。

於是就好了。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9

#define maxn 800005

10using

namespace

std;

11int

t,na,nb,m,cnt,rt,la,al;

12int head[maxn],tot,pl[maxn],f[maxn][22],out

[maxn],top[maxn];

13long

long dp[maxn];char

ch[maxn];

14 vectorg[maxn],p[maxn];

15struct nodee[maxn*2

];16

struct

nos[maxn];

19struct

nodea[maxn],b[maxn];

22void

q()28 cnt=rt=la=1;tot=0

;29 memset(f,0,sizeof

f);30 memset(s,0,sizeof

s);31}32

void ins(int c,int

id)47}48

}49void dfs(int k,int

fa)53

bool cmp(int a,int

b)61

void add(int t1,int

t2)65

void

init()

70 scanf("

%d",&na);for(int i=1;i<=na;i++)scanf("

%d%d

",&a[i].l,&a[i].r),a[i].len=a[i].r-a[i].l+1

;71 scanf("

%d",&nb);for(int i=1;i<=nb;i++)scanf("

%d%d

",&b[i].l,&b[i].r),b[i].len=b[i].r-b[i].l+1;72

for(int i=1;i<=cnt;i++)g[s[i].par].push_back(i);

73 dfs(rt,0

);74

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

75for(int i=1;i<=cnt;i++)f[i][j]=f[f[i][j-1]][j-1

];76

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

81 p[t].push_back(cnt+i);82}

83for(int i=1;i<=nb;i++)

88 p[t].push_back(cnt+na+i);89}

90for(int i=1;i<=cnt;i++)sort(p[i].begin(),p[i].end(),cmp);

9192

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

99 top[i]=lb;

100}

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

102if

(s[i].par)

105 cin>>m;

106for(int i=1,t1,t2;i<=m;i++)

110 al=cnt+na+nb;

111}

112void

tp()

122}

123for(int i=1;i<=al;i++)if(out[i]>0)

124long

long ans=0

;125

for(int i=1;i<=al;i++)ans=max(ans,dp[i]);

126 cout

127}

128int

main()

135return0;

136 }

view code

字串問題 翻轉字串

題目 給定乙個字元型別的陣列chas,請在單詞間做逆序調整,只要做到單詞順序逆序即可,對空格的位置沒有特別要求。例如把chas看成字串為 i love you 調整成 you love i 補充題目 給定乙個字元型別的陣列chas和乙個整數size,請把大小為size的左半區整體移到右半區,右半區整...

字串問題

char str1 abcd char str2 efgh str1 str2 這個操作是合法的,結果也是正確的 這兩個字串都是儲存在棧上,可以修改其中的內容。其中,str1 str2相當於把str2字串的第乙個字元 e 賦給了str1的第乙個字元,因此,str1就變成了 ebcd 但是如果用字串指...

字串問題

ll是什麼?這都不知道的話,別說自己是程式猿啊!longlong?肯定是lovelive啊!qwb為了檢驗你是否是真正的程式猿,決定出道題考考你 現在程式會輸入一行字串,如果恰好是lovelive 不區分大小寫 就輸出yes,否則輸出no。輸入有多組 組數不超過100 每組輸入一行字串 字串長度不超...