loj
二分答案 \(mid\).
考慮字尾陣列求出的陣列,那麼只要看 \(sa\) 陣列裡的
包含 \(c\) 開頭的字尾的
一段滿足最長公共字首 \(\geq mid\) 的區間裡,有沒有開頭在 \([a,b-mid+1]\) 中的字尾即可.
(可能上面那段話太模糊,請繼續看下去)
具體來說,先求出乙個 \(l\),滿足 \(sa\) 陣列中 \([l,c]\) 這段區間的最長公共字首都 \(\geq mid\).
再求 \(r\),滿足 \(sa\) 陣列中 \(c,r\) 這段區間的最長公共字首 \(\geq mid\).
那麼如果有開頭
在 \(sa\) 陣列中的 \([l,r]\) 範圍內,
且在原串中 \([a,b-mid+1]\) 內
的字尾,
則答案 \(\geq mid\).
那麼 \(l,r\) 可以在求出 \(height\) 陣列的 \(\texttt\) 表後,二分答案求.
而判斷 \([l,r]\) 中是否有開頭在 \([a,b-mid+1]\) 中的點的字尾,
可以以 \(rk\) 作為下標,建主席樹,
每次查詢 \([a,b-mid+1]\) 中的下標在 \([l,r]\) 中的個數,如果 \(>0\) 則說明存在.
這題需要對字尾陣列,主席樹的靈活運用,並需要一些做題技巧(二分答案).
#include #include #include #define ll long long
using namespace std;
inline int read()
while(c<='9'&&c>='0')
return f*sum;
}const int n=200005;
int n,q;
char ss[n];
namespace sa
int k=0;
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++) s[i][0]=ht[i];
for(int j=1;j<18;j++)
for(int i=1;i<=n;i++)
if(i+(1<<(j-1))<=n) s[i][j]=min(s[i][j-1],s[i+(1<<(j-1))][j-1]);
lg[0]=-1;
for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
} inline int lcp(int l,int r)
inline int query(int p1,int p2,int l,int r,int ql,int qr)
};using namespace tr;
signed main()
l=rk[c];r=n;
while(l<=r)
if(query(rt[a-1],rt[(mid? b-mid+1:b)],1,n,pl,pr)) ans=mid,l=mid+1;
else r=mid-1;
} printf("%d\n",ans);
} return 0;
}
題解 SDOI2016 征途
link 題目大意 給定序列,將它劃分為 m 段使得方差最小,輸出 s 2 m 2 乙個整數 text 這題我通過題解中的大佬部落格學到了一般化方差柿子的寫法。下面來推柿子 s 2 frac n x i overline 2 frac sum n x i 2 n frac n x i 2 2 sum...
SDOI2016 遊戲題解
這道題太噁心了,調了我整整一晚上,結果發現是乙個bi 錯誤,多多捂臉 這道題比之前的題多了乙個初始化和區間查詢的操作,主要是區間查詢噁心 因為要區間查詢,所以必須維護區間最低點,修改和查詢操作被改得面目全非。我們要維護的話,必須從現值,子值,新值,具體的不好多說 看 吧 include define...
2016程設期末偽題解
期末發揮實在是太差了 比2015年少了好多送分題,整體難度顯得很大,但是考完之後靜下來做又覺得並不是很難orz 1.籃球聯賽 暴力列舉 我用的 dfs 來列舉 2.奪寶探險 暴力 dfs 3.尋找邊緣 從邊緣暴力 dfs 4.猴子摘桃 可以直接用兩個指標指向區間端點做到 o n 5.分形盒 直接遞迴...