2024.11.2 模拟赛

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

posted @ 2024-11-03 11:14  PassName  阅读(38)  评论(0编辑  收藏  举报