9 24 模擬賽T1括號序列

2021-09-27 09:55:34 字數 2308 閱讀 6121

【問題᧿述】

給定乙個括號求正確使用括號的字串。

【輸入檔案】

輸入檔案包括一行乙個字串,為給定的括號序列。

【輸出檔案】

輸出乙個整數,為標準的括號序列的子串的個數。

【輸入輸出樣例】

()(())

4【資料規模和約定】

設輸入字串的長度為n。

對於30%的資料,滿足n

≤200

n ≤ 200

n≤200。

對於60%的資料,滿足n

≤5000

n≤ 5000

n≤5000

。對於100%的資料,滿足1≤n

≤106

1 ≤ n≤ 10^6

1≤n≤10

6。正解真的是好優秀,當時只打了暴力,加了一點剪枝,60%的資料還過了幾個,

然後又去問了乙個80分做法???(也是卡過資料的)

顯然30分左右暴力直接列舉兩個端點判斷是否是乙個合法括號序列,dfs判讀端點內是否合法,對於乙個串,如果起點或者終點就不像是合法(比如長這樣)..

.)

) ... )

)...

))的我們就直接跳過,對於不能跳過的,我們就開乙個計數器,遇到「(」

「(」「(

」就加一反之減一如果他合法那麼在終點時和一定為零,並且在中間的時候不會出現負數的情況因為出現負數說明括號是反著的,像這樣())

((

)())(()

())(()

這樣在結尾的時候和是零但是中間會出現負數,然後我們暴力判斷變負數就退出,跑到列舉的右端點為0就答案加一即可。

80分

這個大佬應該會寫,畢竟是她教的

(太累了,先鴿著,有空再補)

100分

如果你看了我的暴力解法的話,可能會覺得有好多好多優化的方法,但是我中間開,同時到第一題時有點不想寫,滿腦子都是棧的寫法我不會寫,就隨便寫了個暴力敷衍了一下,雖然自己感覺可以優化但是沒有寫。

那麼我們現在掃一遍字串,同樣是遇到"(「加一遇到」)"減一,那麼我們在知道暴力判斷合法的情況下,考慮怎麼把這個判斷從n2的左右端點中移除出來,(我大約n3的做法居然過了35分,對於30%的資料n≤200);

顯然我們列舉再判斷的時候有大量的區間被重複掃瞄了,那麼我們考慮什麼時候合法,

在暴力中顯然是從左到右掃到零的時候,那麼在一次性掃的時候就是前後在掃過兩個點的時候他們的計數器的值都是相等的時候,那麼內部合法就是在從左到右的時候左右兩端時的數值是最小的

如果我們只考慮計數器值相等這乙個條件,我們開乙個長度為2n2n

2n的陣列,這裡我用的是sum[2n],從i=1

i = 1

i=1到n

nn 開始掃,記錄計數器num每個值出現的次數每次答案加上之前出現的次數就行,就是ans

+=su

m[nu

m+n]

,++s

um[n

um+n

]ans+= sum[num + n],++sum[num + n]

ans+=s

um[n

um+n

],++

sum[

num+

n]sum + n是為了防止下標越界,防止開始時num減成負數,陣列沒法存

那麼我們想想怎麼判斷合法,或者說濾除不合法的貢獻,因為你可能對前乙個有貢獻,中間不合法,對後面實際上是不能有貢獻的。

講到這裡,保證合法的方法就出來了,對於乙個num[i]如果存在num[i + k] = num[i],那麼以i+k的合法序列左端點不會小於i,,那麼如果前面仍然出現了num[i - t] = num[i]就會出現多餘的貢獻,所以我們每次統計答案的時候就在統計完的時候把之前統計的個數清零。而能出現num[i] = num[i + k]的時候只能是在num值向下減的時候,所以在s[i] == ')'的時候操作就行了

#include

#define maxn 5000010

#define ll long long

using namespace std;

char s[maxn]

;int sum[maxn]

;int

main()

else

}printf

("%lld\n"

, ans)

;return0;

}

4 21小A模擬賽 T1

description 乙個無限長的01 序列,初始全為0,每次選擇乙個區間 l,r 進行操作,有三種操作 1 l r 將 l,r 中所有元素變成1。2 l r 將 l,r 中所有元素變成0。3 l r 將 l,r 中所有元素異或上1。每次操作後詢問最左邊的0 在哪個位置。input format ...

YCH的模擬賽 T1

括號序列問題,往往就是把左括號看成 1,右括號看成 1,我們只需要保證任意乙個字首大於等於0,且總和為0,就代表是個合法括號序列了。令 f i j 表示當前到第 i 個字元,現在的字首和 j 那麼分三種情況考慮。若第 i 1 個字元是左括號,則能轉移到 f i 1 j 1 若第 i 1 個字元是右括...

11 12 模擬賽T1 加密

有一種不講道理的加密方法是 在字串的任意位置隨機插入字元。相應的,不講道理的解密方法就是從字串中恰好刪去隨機插入的那些字元。給定原文?和加密後的字串?求?有多少子串可以通過解密得到原文?輸入第一行包含乙個字串?第二行包含乙個字串?輸出一行,包含乙個整數,代表可以通過解密得到原文的?的子串的數量。ab...