2024.11.2 模擬賽

PassName發表於2024-11-03

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