一、F - 小沙的算术
知识点:复杂度分析;并查集应用;并查集思想(数组实现,建立联系);可以开一些无用空间不填东西或者初始化成一个值;逆元、模计算;从后往前看问题(延时一步);从前往后看问题
首先分析这个问题的复杂度,把问题取个极限。比如这个题,如果全是乘法,按照我最朴素的模拟想法,即从乘法开始用指针找到加号为止,时间为1e6,不可取;如果全是一个乘法一个加法,则最多有1e6/2组,如果是用记录左和右坐标的方法还是不行。
这个问题的关键是 划分组别
二、价值序列
int T, n, a[maxn], b[maxn], num[maxn];
bool vis[maxn];
ll t[maxn];
read(T);
t[0] = 1;
rep(i, 1, maxn - 1) t[i] = t[i - 1] * 2 % mod;
while (T--) {
read(n);
rep(i, 1, n) { read(a[i]); }
int cnt = 0;
rep(i, 1, n) {
b[++cnt] = a[i];
num[cnt] = 1;
while (i < n && a[i] == a[i + 1]) {
++i;
++num[cnt];
}
}
vis[1] = vis[cnt] = true;
rep(i, 2, cnt - 1) {
if (b[i] > b[i - 1] && b[i] > b[i + 1])
vis[i] = true;
else if (b[i] < b[i - 1] && b[i] < b[i + 1])
vis[i] = true;
}
ll res = 1;
rep(i, 1, cnt) {
if (!vis[i]) {
res = res * t[num[i]] % mod;
} else {
res = res * (t[num[i]] - 1 + mod) % mod;
}
}
print(res, '\n');
rep(i, 1, cnt) vis[i] = false, num[i] = 0;
}