2024.11.2 模擬賽
T1 P11242 碧樹
把 \(n\) 個點往外連即可。最終答案為 \(n - \max_{i=1}^na_i + 1\)
T2 P11243 繁花
感覺我的做法麻煩了,而且隨機複雜度()
顯然的,從左往右看可以分層,遇到一次大於號分一次。對於每段,遍歷一遍,每遇到一次小於號計算一次答案。如果不考慮等於號,這段的貢獻就是當前下標與右邊離自己最近的小於號的下標之差。如果有等於號,考慮有幾個等於號連著就可以了,開個 lst
維護一下下標位置就可以 \(O(1)\) 查詢了。將原來的貢獻乘上 \(i- lst_i\) 即可。
計算答案的時候從左往右算一遍再從右往左算一遍就可以了。
但是這麼寫會被卡到 \(O(n^2)\),沒關係,我們繼續最佳化,再開一個 \(ne[i]\) 維護最近的小於號,如果 \(ne_j > i\) ,那就沒有必要繼續往回算找答案了。直接進行下一次計算。這樣複雜度可以直接最佳化到接近線性?不知道,反正跑的飛快。
#include <bits/stdc++.h>
#define rint register int
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e7 + 5;
char s[N], t[N];
int n;
int lst[N], ne[N];
int calc(char s[])
{
for (rint i = 1, j = 0; i <= n; i++)
{
lst[i] = j;
if (s[i] != '=') j = i;
}
for (rint i = n, j = 1e6; i >= 1; i--)
{
if (s[i] == '<') j = i;
ne[i] = j;
}
int ans = 0;
for (rint i = 1, j = 1; i <= n; i++)
{
if (s[i] == '>')
{
if (ne[j] > i) continue;
for (rint k = j; k < i; k++)
if (s[k] == '<')
{
ans += (i - k) * (k - lst[k]);
j = i;
}
}
}
return ans;
}
signed main()
{
int T;
cin >> T;
while (T--)
{
cin >> n;
for (rint i = 1; i < n; i++) cin >> s[i];
s[n] = '>';
for (rint i = 1; i < n; i++)
{
if (s[n - i] == '>') t[i] = '<';
else if (s[n - i] == '<') t[i] = '>';
else t[i] = '=';
}
t[n] = '>';
cout << calc(s) + calc(t) << endl;
}
return 0;
}
T3 P11244 吻秋
不是,這 tm 什麼玩意兒,正常人不應該都想的是線段樹合併維護操作 1 然後平衡樹查詢第 k 大嗎()
賽時寫完暴力後開始想正解,但是除了線段樹合併 + 平衡樹想不到別的做法了。但是好多人 20min 切掉 T3 又讓我覺得很不可思議,感覺自己又想歪了但是好像又沒歪,然後寫了兩個小時寫了一坨跑的比暴力還慢無語了放棄了。
想到排序操作肯定有多餘的,因為記錄一下值域範圍,如果有交集再計算否則不用管。所以我們只需要維護每一個序列的最大值最小值,然後打個 tag 讓每個序列排上一次序就夠用了,剩下的只需要歸併排序就可以了,直接呼叫 merge 函式。所以只有前幾次操作時暴力維護的後邊的操作大機率都是 \(O(1)\) 的比個最值就行
具體複雜度證明不太會
record
T4 P11245 殘雪
沒時間了賽時就構造出了特殊性質,非常好構造題使我大腦飛速旋轉。
先計算 \(L=R\) 的情況,我們假設 \(n<m\) ,那麼可以理解為要去找使 \(n\) 不會被吸收的合法解的對於 \(m\) 的要求。顯然,如果我們 \(L\) 個 \(L\) 個去排波峰波谷是最能讓他被吸收的排法。那麼只需要把週期降低為 \(L-1\),它就一定吸收不了了。那麼對於 \(m\) 的限制,就是必須大於週期數乘上 \(L+1\)。
考慮 \(L<R\) 的情況。我們上邊找對於 \(m\) 的限制,其實就是往 \(n\) 個波峰裡面插入一定量的波谷。我們仍然按照 \(L-1\) 去排,然後每次使 \(L\) 變大去改我們的構造出來的序列,發現每 \(2L\) 個為一組,第一組為 \(L - 1\) 個波峰 \(L + 1\) 個波谷,然後往後的每一組依次解體 \(R - L\) 個波峰 直到不存在連續的波峰。那麼我們的構造方案就出來了。
最後,我們假設的是 \(n<m\),不失一般性的,我們計算答案時只需要對於 \(n\) 算一遍 \(m\) 是否滿足要求然後對 \(m\) 算一遍 \(n\) 是否滿足要求即可。
record