Jzoj4209 已經沒有什麼好害怕的了

2021-08-14 17:21:05 字數 1069 閱讀 3375

小y 最近開始學習演算法姿勢,但是因為小r 非常bb,給了她很多b6 題,所以她覺得自己已經沒有什麼前途了。

於是小r 給了她一些稍微簡單的題,讓她覺得已經沒有什麼好害怕的了,其中一道是這樣的:

給定乙個長度為n 只包含左括號和右括號的序列,現在小r 想要知道經過每乙個位置的合法子串有多少個。

空串是乙個合法的串,如果a 和b 都是合法的串,那麼(a) 和ab 都是合法的串。 n<=1000000

又是差分的題目,非常坑

先給括號配對,讓後記一對合法的括號為[l,r)

我們分別按順序和倒序處理每對括號[l,r)

對於括號[l,r)我們先對區間[l,r)加上1,讓後考慮它的影響

若l是另一對括號[l',r')的右端點(r'=l)那麼顯然這裡的[l,r)貢獻可以全部加過去

若r是另一對括號[l',r')的左端點,那麼顯然也可以把[l,r)的貢獻全加過去

不合法的括號位置會自動抵消

#pragma gcc optimize("o3")

#pragma g++ optimize("o3")

#include

#include

#include

#define n 1000010

#define m 1000000007

using

namespace

std;

long

long ans,f[n]; char s[n];

int n,m,t,w[n],l[n],r[n],cl[n],cr[n];

int _18520()

for(int i=n+1;i;--i) cr[l[i]]+=++cr[i];

for(int i=1;i<=n;++i) cl[r[i]]+=--cl[i];

for(int i=1;i<=n;++i) f[i]=f[i-1]+cl[i]+cr[i];

for(int i=1;i<=n;++i) ans=ans+i*f[i]%m;

printf("%lld\n",ans);

}int main()

}

Jzoj4209 已經沒有什麼好害怕的了

小y 最近開始學習演算法姿勢,但是因為小r 非常bb,給了她很多b6 題,所以她覺得自己已經沒有什麼前途了。於是小r 給了她一些稍微簡單的題,讓她覺得已經沒有什麼好害怕的了,其中一道是這樣的 給定乙個長度為n 只包含左括號和右括號的序列,現在小r 想要知道經過每乙個位置的合法子串有多少個。空串是乙個...

jzoj4209 已經沒有什麼好害怕的了 差分

ans ians i ansi 表示包含字元i ii的括號匹配子串個數 求 i 1n a nsi imod 1e9 7 sum n ans i i mod 1e9 7 i 1 n ans i i mod 1e9 7 計算出每個匹配括號的前乙個括號位置和後乙個括號位置。乙個差分陣列 先計算加的,其實對...

已經沒有什麼好害怕的了

給定乙個長度為n 只包含左括號和右括號的序列,求每乙個位置經過的合法子串有多少個。空串是乙個合法的串,如果a 和b 都是合法的串,那麼 a 和ab 都是合法的串。令a ns i 為第 i 位的答案,對於每組資料,輸出乙個整數an s 1 n an s i imo d p p 1 9 7 n 10 6...