0
点赞
收藏
分享

微信扫一扫

集合多对一

沈芏 2022-02-20 阅读 42

一、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;
    }
举报

相关推荐

0 条评论