首页 > 其他分享 >蓝桥杯省赛题目选解

蓝桥杯省赛题目选解

时间:2023-04-04 22:34:09浏览次数:30  
标签:cnt return int mn tr 蓝桥 add 省赛 选解

[蓝桥杯 2022 省 A] 最长不下降子序列

Tag:dp,树状数组,离散化

题意

可以修改最多连续 \(k\) 个数为同一个数,求\(LIS\)长度。\(10^5\)。

题解

分别求出以 \(i\) 开头和结尾的 \(LIS\) 长度\(g[i],f[i]\)

最后拼接 \(g[i] + k + \max\limits_{a[j] \le a[i]}{f[j]}\)即可

//
// Created by blackbird on 2023/4/4.
//
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;

int n, k, a[N], f[N], g[N];

struct Fenwick_Tree {   //树状数组维护前缀最大值
    int c[N];
    int add(int i, int x) {
        for (; i <= n; i += i & -i)
            c[i] = max(c[i], x);
    }
    int ask(int i) {
        int res = 0;
        for (; i; i -= i & -i)
            res = max(res, c[i]);
        return res;
    }
} F, G, T;

int work() { //离散化
    vector<int> vec;
    for (int i = 1; i <= n; i++) vec.push_back(a[i]);
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    for (int i = 1; i <= n; i++) a[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1;
}



int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    work();
    a[0] = 1; a[n + 1] = n + 1;//注意:树状数组不能用下标0

    for (int i = 1; i <= n; i++) {
        f[i] = F.ask(a[i]) + 1;
        F.add(a[i], f[i]);
    }

    for (int i = n; i >= 1; i--) {
        g[i] = G.ask(n - a[i] + 1) + 1;
        G.add(n - a[i] + 1, g[i]);
    }
    int ans = 0;
    for (int i = k + 1; i <= n + 1; i++) {
        T.add(a[i - k - 1], f[i - k - 1]);
        ans = max(ans, T.ask(a[i]) + k + g[i]);
    }
    cout << ans << "\n";
    return 0;
}

[蓝桥杯 2013 省 B] 连号区间数

Tag: 线段树,单调栈

题意

给定一个排列,求满足\(\max\limits_{l\le i\le r} p_i-\min\limits_{l\le i\le r} p_i=r-l\)的子区间数量。\(5\times 10^4\)。

题解

设\(f_l=\max-\min + l-r\),显然 \(f\) 的最小值是 \(0\)。

考虑右端点 \(r\) 从 \(1\) 到 \(n\) 移动,维护区间 \([1,r]\) 的 \(f_l\) ,并查询最小值数量。

//
// Created by blackbird on 2023/4/4.
//
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 10;
int n, a[N];

struct tree {
    int min, add, cnt;
} tr[N << 2];

#define mid (l+r>>1)
#define ls (u<<1)
#define rs (u<<1|1)

void pushup(int u) {
    tr[u].min = min(tr[ls].min, tr[rs].min);
    tr[u].cnt = 0;
    if (tr[ls].min == tr[u].min) tr[u].cnt += tr[ls].cnt;
    if (tr[rs].min == tr[u].min) tr[u].cnt += tr[rs].cnt;
}
void pushdown(int u) {
    if (!tr[u].add) return;
    tr[ls].min += tr[u].add; tr[ls].add += tr[u].add;
    tr[rs].min += tr[u].add; tr[rs].add += tr[u].add;
    tr[u].add = 0;
}

void build(int l, int r, int u) {
    if (l == r) {
        tr[u].cnt = 1;
        return;
    }
    build(l, mid, ls); build(mid + 1, r, rs);
    pushup(u);
}

void add(int s, int t, int l, int r, int u, int k) {
    if (s > t) return;
    if (s <= l && t >= r) {
        tr[u].min += k;
        tr[u].add += k;
        return;
    }
    pushdown(u);
    if (s <= mid) add(s, t, l, mid, ls, k);
    if (t >= mid + 1) add(s, t, mid + 1, r, rs, k);
    pushup(u);
}

int query_cnt(int s, int t, int l, int r, int u) {
    if (s > t) return 0;
    if (s <= l && t >= r) {
        return tr[u].min == 0 ? tr[u].cnt : 0;
    }
    pushdown(u);
    int res = 0;
    if (s <= mid) res += query_cnt(s, t, l, mid, ls);
    if (t >= mid + 1) res += query_cnt(s, t, mid + 1, r, rs);
    return res;
}

int smx[N], smn[N], cmx, cmn;

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    build(1, n, 1);

    int ans = 0;
    stack<int> mx, mn;//单调减/增栈
    for (int i = 1; i <= n; i++) {
        // mx - mn + l - r
        // r : += 1
        add(1, i - 1, 1, n, 1, -1);
        // mx: a[tp] -> a[i]
        while (!mx.empty() && a[mx.top()] <= a[i]) {
            int tp = mx.top(); mx.pop();
            int pre = mx.empty() ? 0 : mx.top();
            add(pre + 1, tp, 1, n, 1, a[i] - a[tp]);
        }
        mx.push(i);
        // mn: a[tp] -> a[i]
        while (!mn.empty() && a[mn.top()] >= a[i]) {
            int tp = mn.top(); mn.pop();
            int pre = mn.empty() ? 0 : mn.top();
            add(pre + 1, tp, 1, n, 1, a[tp] - a[i]);
        }
        mn.push(i);
        ans += query_cnt(1, i, 1, n, 1);
    }
    cout << ans << "\n";
    return 0;
}

标签:cnt,return,int,mn,tr,蓝桥,add,省赛,选解
From: https://www.cnblogs.com/vv123/p/17288127.html

相关文章

  • 蓝桥杯4天冲刺1
    今晚得知这周六蓝桥杯,然而我还没复习:)已经一面多没碰C了我真的会谢(报名的时候也没想到这学期这么忙哇TAT)关键蓝桥杯考试时间和外包杯的题目截止时间几乎重合!!!唉……多说无益,复习吧还是 因为知道的太晚了,目前只复习了sort函数头文件#include<algorithm>默认升序排序(1,2,3......
  • 蓝桥杯(全球变暖dfs)
    蓝桥杯(全球变暖dfs)importjava.util.Scanner;/***该题使用了深度优先算法dfs用于把相连的#号当成一块大陆,并通过数组记录下有几块大陆*dfs算法并不难,只要对用dfs处理过后留下的aes数组和sea数组进行处理得到结果即可*我的思路就是*1、sea数组记录源数据,然后判断是......
  • 2023蓝桥杯省赛C/C++组备赛
    一、简单计算与模拟1.成绩统计#include<bits/stdc++.h>usingnamespacestd;intn;intmain(){ doublepoint; doublejige=0,youxiu=0; cin>>n; for(inti=0;i<n;++i){ cin>>point; if(point>=60){ jige++; if(point&......
  • (4.3)数组、对象及类数组对象,set的用法,正则表达式的常用方法,蓝桥杯备赛-(生成数组、数
    1.1数组、对象及类数组对象1.数组:​ 数组是有序的数据集合,其中的索引值从0开始递增,并且数组有length属性,可以获取数组内的元素个数,其中的值可以是任何的数组类型。2.对象:​ 对象是无序的是由一个或多个键值对组成的数据集合,对象没有length属性。3.伪数组(类数组对象):​ ......
  • [2022年蓝桥杯C/C++ A组]个人做题记录
    碎碎念欸嘿,鸽了小半年去做了一些不喜欢的事情,但兜兜转转,还是acm最香捏求和题意求\(\sum_{i=1}^n\sum_{j=1}^na_i*a_j(i!=j)\)题解感觉是去年的时候笨人唯一做满分的题……经典前缀和,设\(sum[i]=\sum_{j=i}^na[j]\),答案即为\(\sum_{i=1}^{n-1}a[i]*sum[i+1]\)#definein......
  • [每天例题]蓝桥杯 C语言 单词分析
    蓝桥杯C语言单词分析题目  题目要求1.寻找出现最多的字母和这个字母出现的次数。2.如果有多个字母出现的次数相等,输出字典序最小的那个。思路分析输入方法:方法一:1.可以通过数组来记录该单词,并为单词出现的每一个字母做上标记。2.可以采用for循环将字符串依次输......
  • 2018年第九届蓝桥杯—B组C/C++程序设计省赛解题-2明码
    .明码汉字的字形存在于字库中,即便在今天,16点阵的字库也仍然使用广泛。16点阵的字库把每个汉字看成是16x16个像素信息。并把这些信息记录在字节中。一个字节可以存储8位信息,用32个字节就可以存一个汉字的字形了。把每个字节转为2进制表示,1表示墨迹,0表示底色。每行2个字节,一共16......
  • 洛谷 P8742 [蓝桥杯 2021 省 AB] 砝码称重
    经典01背包题首先介绍一下01背包,即一种DP问题,以放置物品为模型,每个物品只能放一次。其区分于完全背包(每个物品可以放无限多次),以及多重背包(每个物品有一个固定次数上限)。题中给出了$N$个砝码及每个砝码的质量,要求我们求出可以称出质量的种数。由此想到转化为01背包。......
  • 洛谷 P8762 [蓝桥杯 2021 国 ABC] 123 题解
    为什么可以使用前缀和,这里提供解释:初读题目,我们发现这个数列很迷惑,似乎不能使用数学方法来解。\[1,1,2,1,2,3,1,2,3,4,\cdots\]但是,我们可以想到数形结合的方式,我们将数列看作一个三角形,于是他变成了:\[1\]\[1,2\]\[1,2,3\]\[1,2,3,4\]\[\cdots\cdots\]于是本题变得好思......
  • 2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组真题
    2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组真题卡牌constintN=2e5+10;piia[N];intsum;intb[N];intn,m;voidsolve(){ intmx=1e18,ans=0; cin>>n>>m; for(inti=1;i<=n;i++)cin>>a[i].first,a[i].second=i; for(inti=1;i<=n;i++)cin>>b[i......