首页 > 其他分享 >2024大试牛刀5题解

2024大试牛刀5题解

时间:2024-02-09 10:12:55浏览次数:33  
标签:std 大试 前缀 int 题解 2024 prefix ans oplus

鼠鼠我鸭

没学过前缀和的自己去补一下,这里不过多赘述(其实是我不想写)

以第二组数据为例:

类型 0 1 0 0
体重 2 5 6 5

先计算出不使用魔法时鸭鸭的重量,当作基础值\(ori=5\)。

然后来看看对一段区间使用魔法会造成什么效果:

类型 0 1 0 0
体重 2 5 6 5
变化a +2 -5 +6 +5

比如,如果选择了区间\([1,2]\),我们得到的答案就是\(ans=ori+2-5=2\)。​

于是这个问题就变成了对\(a\)​​数组求最大子段和。

特别地,如果最大子段和为负,答案是前面算的基础值。


我们已知可以利用前缀和快速求出一段区间的和,就像这样\(fix=prefix[r]-prefix[l-1]\)​。

所以现在需要做的事情就是找到这个区间的两端\(l\)和\(r\)。

可以采用以下这种方法:

枚举区间的右端点,此时\(prefix[r]\)就确定下来了。

那么要让\(fix\)最大,就要让\(prefix[l-1]\)最小。

\(\mathscr{finish}\)

void solve()
{
    int n;cin >> n;
    for (int i = 1; i <= n; ++ i)std::cin >> a[i];
    for (int i = 1; i <= n; ++ i)std::cin >> w[i];

    ll ori = 0;//不使用魔法的结果
    for (int i = 1; i <= n; ++ i) ori += a[i] * w[i];

    ll mn = 0, fix = 0;//mn表示min(prefix[j]),0 <= j < i
    for (int i = 1; i <= n; ++ i)
    {
        prefix[i] = prefix[i - 1] + (a[i] ? -1 : 1) * w[i];
        fix = std::max(fix, prefix[i] - mn);
        mn = std::min(mn, prefix[i]);
    }
    std::cout << ori + fix << '\n';
}

二维前缀和

这个题其实也可以用\(n\)个一维前缀和,我做的数据没有刻意卡这种做法,但是这样每次查询的复杂度是\(O(n)\),真到比赛的时候想卡掉其实也不难。

定义一个二维数组\(prefix\),其中\(prefix[i][j]\)存储从\((1,1)\)到\((i,j)\)这个矩阵所有元素的和。

查询的过程可能有点抽象,这里贴张图

比如,要查询红色矩阵中所有元素的和\(sum_红=绿-蓝-黄+紫\)​。(注意紫色部分减了两次,要加一次)

这样就结束了

void solve()
{
    int n, m, q;std::cin >> n >> m >> q;
    for (int i = 1; i <= n; ++ i)
        for (int j = 1; j <= m; ++ j)
            std::cin >> a[i][j];
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++)
            p[i][j] = p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1] + a[i][j];
    while(q --)
    {
        int x1, x2, y1, y2;
        std::cin >> x1 >> y1 >> x2 >> y2;
        ll ans = p[x2][y2] - p[x1 - 1][y2] - p[x2][y1 - 1] + p[x1 - 1][y1 - 1];
        std::cout << ans << '\n';
    }
}

我们需要0

这个题单纯考一点异或的性质,不会直接百度,直接上计算过程,以\(n\)为\(5\)举例:

  • \(b_1\oplus b_2\oplus b_3\oplus b_4\oplus b_5=0\)

  • \(a_1\oplus x\oplus a_2\oplus x\oplus a_3\oplus x\oplus a_4\oplus x\oplus a_5\oplus x=0\)

  • \(a_1\oplus a_2\oplus a_3\oplus a_4\oplus a_5\oplus x\oplus x\oplus x\oplus x\oplus x=0\)

  • \(a_1\oplus a_2\oplus a_3\oplus a_4\oplus a_5\oplus x=0\)

  • \(a_1\oplus a_2\oplus a_3\oplus a_4\oplus a_5=x\)

已经说明\(n\)为奇数,所以推最后一定会剩一个\(x\),也就是这样\(a_1\oplus a_2\oplus a_3...\oplus x=0\)。

所以\(x\)一定存在且唯一,没有输出-1的情况。

void solve()
{
    int n;std::cin >> n;
    ll ans = 0;
    for (int i = 1; i <= n; ++ i)
    {
        int x;cin >> x;
        ans ^= x;
    }
    std::cout << ans << '\n';
}

标签:std,大试,前缀,int,题解,2024,prefix,ans,oplus
From: https://www.cnblogs.com/xaviertse/p/18012344

相关文章

  • [THUPC2024] 分治乘法
    [THUPC2024初赛]分治乘法题目描述小艾想要挑战分治乘法。TA将策略抽象成了如下问题:现在给定一个目标集合\(T\),该集合是\(\{1,\dots,n\}\)的一个子集(\(1\leqn\leq5\times10^5\))。你需要通过一系列操作构造一些集合最后得到\(T\),具体来说有以下三种操作:创造一个大小......
  • ABC338G题解
    也许是一个简单一点的做法?假如我们要求一个表达式的值,我们求的顺序显然是,按照加号划分为若干段,段内只有数字和乘号,计算出段内结果后全部加起来。称一个只有数字和乘号的表达式是基本表达式,我们将每个表达式的贡献拆分为若干个基本表达式之和,那么我们就可以枚举每个基本表达式,算......
  • 「JOI 2024 Final」礼物交换
    [link](https://loj.ac/p/4092)考虑单次询问怎么做。不难发现这是一个二分图匹配,左部点$i$可以匹配到右部点$j$当且仅当$A_i\geB_j\andi\neqj$。不妨设$B$递增,这当然可以通过排序实现。什么时候不存在完美匹配呢?就是存在左部点$i$,$i$只能匹配到右部点$[1,i-1]$(也......
  • CF516D Drazil and Morning Exercise 题解
    Description给定一棵\(n\)个点的树,边有边权。定义\(f_x=\max_{i=1}^n\text{dist}(x,i)\)。\(q\)次询问最大的满足\(\max_{x\ins}f_x-\min_{x\ins}f_x\lel\)的连通块\(s\)包含的点数。\(n\le10^5\),\(q\le50\)。Solution这里\(f_u\)显然可以用换......
  • 2024年锦鲤化龙网络赛
    A自相残杀:题目链接题目大意:在\(n\timesn\)的棋盘上摆放\(k\)头恶龙,使得每头恶龙都能相互攻击到对方的方案数。解题思路:模拟,找规律。当\(k\gt4\)时,无论怎么摆放,方案数都是\(0\)种,直接输出\(0\)当\(k\le4\)时,分类讨论:\(o\)表示摆放恶龙的位置,\(x\)......
  • 2024,写作新征程
    layout:posttitle:"2024,新征程"tags:-"写作"category:"写作"description:"我的《大道至简,给所有人看的编程书》终于在今年最后一天收获了第600个订阅,达到了预设目标。明年,继续努力。"转眼,2023年已过去十分之一了。然而,在大多数人心里,年三十才算是过年,所以,今天是传......
  • CF1771F Hossam and Range Minimum Query 题解
    题目链接:CF或者洛谷比较不错的题,出现奇数次出现的这种问题,比较容易想到一种运算,那就是异或和运算。如果一个区间上一个数出现偶数次,则它对于异或和的贡献为\(0\),那么很显然,我们维护下区间异或和即可判断一个区间上是否存在出现奇数次的数。然后我们注意到\(1\oplus2\oplu......
  • CF1861E Non-Intersecting Subpermutations 题解
    简要题意一个长度为\(n\)的元素在\([1,k]\)的整数序列\(a\)的价值定义如下。初始\(i=1\),如果\(a_{i\simi+k-1}\)包含了\(1\simk\)的所有整数,则价值加\(1\),然后令\(i=i+k\)。如果没有包含\(1\simk\)的所有整数则\(i=i+1\),直到\(i\geqn-k+2\)时结束。......
  • CF1863F Divide, XOR, and Conquer 题解
    简要题意你有两个指针\(l,r\)初始时\(l=1,r=n\)。你可以操作若干次知道\(l=r\)。每次操作你可以选择一个整数\(k\in[l,r)\),记\(x=\bigoplus_{i=l}^ka_i,y=\bigoplus_{i=k+1}^ra_i\)。如果\(x\leqy\),你可以令\(l=k+1\)。如果\(x\geqy\),你可以令\(r=k\)。......
  • P9663 Permutation on Tree 题解
    考虑枚举一个\(x\in[1,n)\),将\(\leqx\)的看作\(0\),\(>x\)的看作\(1\),那么一个排列的贡献实际上就是\(\sum_{x=1}^{n-1}\sum[[p_i\leqx]+[p_{i+1}>x]=1]\)。那么问题转变为一个给定一棵树,每一个点有权值\(0\)或\(1\),求所有排布方案的贡献之和。设\(f_x\)表示......