<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      題解:Luogu P4143 采集礦石

      題意

      給定長度為 \(n\) 的字符串 \(s\) 和權值序列 \(v\)。求所有子串 \(s[l,r]\) 使得 \(s[l,r]\) 在所有子串去重后的字典序降序排名,恰好等于 \(v[l,r]\) 的區間和。\(1\leq n\leq 10^5\)

      題解

      注意到固定左端點 \(l\) 后,隨著右端點 \(r\) 遞增,\(s[l,r]\) 的字典序降序排名單調遞減,\(v[l,r]\) 的區間和單調遞增,因此每個 \(l\) 最多對應一個合法的 \(r\)。考慮對 \(v\) 的區間和和子串的排名的差值二分,找到第一個 \(\geq 0\)\(r\)。現在我們需要對一個子串 \(s[l,r]\),求出其在所有子串去重后的字典序降序排名。

      考察怎樣的子串 \(s[l',r']\)\(>s[l,r]\),要么 \(s[l,r]\)\(s[l',r']\) 的前綴,要么 \(s[l',r']\) 在 LCP 的后一位比 \(s[l,r]\) 對應位置要大。不難發現若 \(s[l',r']>s[l,r]\),則 \(s[l',r''](r'<r''\leq n)\) 也一定 \(>s[l,r]\),所以我們轉而考慮所有合法的 \(s[l',r']\) 對應的后綴 \(suf_{l'}\) 的性質。

      對于第一種 case,相當于固定了一段前綴,那么所有合法后綴的排名必然是一段連續區間 \([L,R]\)。對于第二種 case,我們發現這樣的后綴的排名其實就是 \([R+1,n]\)。因為 \(suf_{rk_R}\) 是排名最大的以 \(s[l,r]\) 為前綴的后綴,那么對于 \(suf_{rk_{R+1}}\) 來說,一定是在一段 LCP 之后,比 \(s[l,r]\) 的對應位大,這就和第二個條件完全契合了。

      所以,所有合法的 \(s[l',r']\) 一定是排名處于 \([L,n]\) 之中的后綴的一段前綴。因此 \(s[l,r]\) 的字典序降序排名,實際上就是排名處于 \([L,n]\) 之中的后綴的本質不同前綴個數,減去 \(r-l\)。注意減去 \(r-l\) 是因為我們會把 \(s[l,r]\) 的真前綴也算進去。套用經典結論,排名在 \([L,n]\) 中的后綴的本質不同前綴個數就是 \(\sum\limits_{i=L}^n(n-sa_i+1)-\sum\limits_{i=L+1}^nht_i\),容易預處理后綴和計算。

      至于 \(L\),可以發現它就是最小的 \(i\),使得排名在 \([i,rk_l]\) 中的后綴的 LCP 長度 \(\geq r-l+1\),用 ST 表維護 \(ht\) 即可二分求出。

      時間復雜度是 \(\mathcal{O}(n\log^2{n})\) 的。

      代碼

      #include <bits/stdc++.h>
      
      using namespace std;
      
      #define lowbit(x) ((x) & -(x))
      typedef long long ll;
      typedef pair<int, int> pii;
      const int N = 1e5 + 5, LGN = 18;
      
      template<typename T> inline void chk_min(T &x, T y) { x = min(x, y); }
      template<typename T> inline void chk_max(T &x, T y) { x = max(x, y); }
      
      int n, sz, val[N], pre[N], lg2[N], ans[N];
      int sa[N], rk[N], trk[N << 1], id[N], pid[N], buc[N], ht[N];
      ll suf1[N], suf2[N];
      char s[N];
      
      struct ST {
      	int f[LGN][N];
      	inline void init() {
      		for (int i = 1; i <= n; ++i) f[0][i] = ht[i];
      		for (int i = 1; i <= lg2[n]; ++i) for (int j = 1; j <= n - (1 << i) + 1; ++j)
      			f[i][j] = min(f[i - 1][j], f[i - 1][j + (1 << i - 1)]);
      	}
      	inline int query(int l, int r) {
      		int k = lg2[r - l + 1];
      		return min(f[k][l], f[k][r - (1 << k) + 1]);
      	}
      } st;
      
      inline void build() {
      	int m = 26;
      	for (int i = 1; i <= n; ++i) ++buc[rk[i] = s[i] - 'a' + 1];
      	for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];
      	for (int i = n; i; --i) sa[buc[rk[i]]--] = i;
      	for (int w = 1, p = 0; p < n; w <<= 1, m = p) {
      		p = 0;
      		for (int i = n - w + 1; i <= n; ++i) id[++p] = i;
      		for (int i = 1; i <= n; ++i) if (sa[i] > w) id[++p] = sa[i] - w;
      		fill(buc + 1, buc + m + 1, 0);
      		for (int i = 1; i <= n; ++i) ++buc[pid[i] = rk[id[i]]];
      		for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];
      		for (int i = n; i; --i) sa[buc[pid[i]]--] = id[i];
      		p = 0, copy(rk + 1, rk + n + 1, trk + 1);
      		for (int i = 1; i <= n; ++i) rk[sa[i]] = (trk[sa[i - 1]] == trk[sa[i]] && trk[sa[i - 1] + w] == trk[sa[i] + w]) ? p : ++p;
      	}
      	for (int i = 1, k = 0; i <= n; ++i) {
      		if (k) --k;
      		while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
      		ht[rk[i]] = k;
      	}
      	for (int i = n; i; --i) suf1[i] = suf1[i + 1] + sa[i], suf2[i] = suf2[i + 1] + ht[i];
      }
      inline int getl(int p, int len) {
      	int l = 1, r = p;
      	while (l < r) {
      		int mid = l + r >> 1, v = mid == p ? len : st.query(mid + 1, p);
      		v >= len ? r = mid : l = mid + 1;
      	}
      	return l;
      }
      inline ll rnk(int l, int r) {
      	int L = getl(rk[l], r - l + 1);
      	return (ll)(n - L + 1) * (n + 1) - suf1[L] - suf2[L + 1] - (r - l);
      }
      
      int main() {
      	ios::sync_with_stdio(0), cin.tie(0);
      	cin >> s + 1, n = strlen(s + 1);
      	for (int i = 1; i <= n; ++i) cin >> val[i], pre[i] = pre[i - 1] + val[i];
      	for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1;
      	build(), st.init();
      	for (int i = 1; i <= n; ++i) {
      		int l = i, r = n;
      		while (l < r) {
      			int mid = l + r >> 1;
      			pre[mid] - pre[i - 1] - rnk(i, mid) >= 0 ? r = mid: l = mid + 1;
      		}
      		if (pre[l] - pre[i - 1] == rnk(i, l)) ans[i] = l, ++sz;
      	}
      	cout << sz << '\n';
      	for (int i = 1; i <= n; ++i) if (ans[i]) cout << i << ' ' << ans[i] << '\n';
      	return 0;
      }
      
      posted @ 2025-10-20 22:09  P2441M  閱讀(4)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人妻精品动漫H无码中字| 亚洲高清aⅴ日本欧美视频| 余姚市| 欧美日产国产精品| 亚洲老女人区一区二视频| 天天夜碰日日摸日日澡性色av| 亚洲欧美综合人成在线| 国产中年熟女高潮大集合| 99在线视频免费观看| 亚洲制服无码一区二区三区| 你拍自拍亚洲一区二区三区| 久久国产精品老人性| 九九综合va免费看| 久久夜色撩人精品国产av| 国产小视频一区二区三区| 中国china体内裑精亚洲日本| 亚洲人成自拍网站在线观看| 国产99久久精品一区二区| 豆国产97在线 | 亚洲| 亚洲高请码在线精品av| 国产精品区一二三四久久| 香港三级韩国三级日本三级| av中文无码乱人伦在线观看| 日韩高清国产中文字幕| 国产乱码精品一品二品| 国产午夜精品一区二区三区不卡| 我国产码在线观看av哈哈哈网站| 久久精品成人无码观看免费| 亚洲av乱码久久亚洲精品| 国产尤物精品自在拍视频首页| 中文人妻无码一区二区三区在线| 亚洲精品国产精品乱码不卡| 欧美性猛交xxxx乱大交丰满| 国产精品天天狠天天看| 无码专区人妻系列日韩精品| 亚洲av无码之国产精品网址蜜芽| 沂南县| 亚洲一区二区三成人精品| 一区二区三区激情都市| 人妻少妇偷人精品一区| 平乡县|