首页 > 其他分享 >1.12 CW 模拟赛 赛时记录

1.12 CW 模拟赛 赛时记录

时间:2025-01-12 12:56:59浏览次数:1  
标签:1.12 赛时 int T1 后缀 rm 考虑 CW 前缀

看题

不是哥们怎么感觉一堆原题但是都不会做
没复习最悲惨的一次

策略肯定还是暴力, 没有什么看上去简单的题

\(\rm{T1}\)

思路

侥幸心理找了一下没有啊, 必须自己想

合法串显然就是满足匹配的串
考虑这种经典问题的常见转化 : 令 ( 为 \(1\) , ) 为 \(-1\) , 合法括号串仅当其任意前缀 \(\geq 0\) 且全串之和 \(= 0\)

先考虑确定 \(i\) 时怎么计算
首先计算 \(T [i : n]\) 中的前缀, 记录所有串和 \(\leq 0\) 的, \(> 0\) 的必定没有作用
然后考虑 \(T [1 : i]\) 中的后缀, 记录所有串和 \(\geq 0\) 的, \(< 0\) 的必定没有作用
有点感性, 但是应该是这样的

考虑答案合并
令 \(f_i\) 表示对于 \(T [i : n]\) 中的前缀, 所有串和 \(= -i\) 串串的个数, 令 \(g_i\) 表示对于 \(T [1 : i - 1]\) 中的后缀, 所有串和 \(= i\) 的串串的个数
容易发现 \(g_i, f_i\) 可以组成一个合法串
考虑方案数即为 \(f_i \times g_i\)

感觉就是这样, 手摸下样例

发现一些问题, \(f_i\) 还要新开一维表示串和, 但是显然是做不到的
令 \(f_{i, j}\) 表示对于所有以 \(i\) 开头的串串, 所有串和 \(= -j\) 串串的个数, 令 \(g_{i, j}\) 表示对于所有以 \(i\) 结尾的串串, 所有串和 \(= j\) 的串串的个数, 考虑怎么做到对于每一个 \(i\) , 快速算出 \(f, g\)

好消息是 \(\mathcal{O} (n^2)\) 能做了

考虑的更深一点, 其实可以对于全串的前后缀做处理进而找到 \(f, g\)
问题变成怎么做才能规避掉对前后缀串和的枚举


理一下

首先是一个基础:
对于 \(i\) 位置结果的统计, 你只需要考虑

  • 以 \(i\) 结尾的后缀中, 串和 \(\geq 0\) 的
  • 以 \(i\) 开头的前缀中, 串和 \(\leq 0\) 的

误区在于你还是要统计不满足考虑条件的作为转移, 不然会漏掉情况

那么具体的, 我们设计状态
令 \(f_{i, j}\) 表示以 \(i\) 结尾的后缀中, 串和为 \(j\) 的
令 \(g_{i, j}\) 表示以 \(i\) 开头的前缀中, 串和为 \(j\) 的

\(f, g\) 的状态转移是容易做到 \(\mathcal{O} (n)\) 的, 考虑 \(i\) 点的答案
容易做到分类讨论

  • 前缀 + \(i\) + 后缀
  • 前缀 + \(i\)
  • \(i\) + 后缀

非常经典的分类, 以后一定要注意不要漏了


但是你发现瓶颈在枚举 \(j\) 上, 怎么办, 必须解决这个问题

这个可能要改一下状态, 或者整体处理
不太会了

实现 \(30 \rm{pts}\)

框架

如上讨论即可

代码

#include <bits/stdc++.h>
#define int long long
const int MAXN = 5206; //41
const int MOD = 1e9 + 7;
namespace calc {
    int add(int a, int b) { return a + b > MOD ? a + b - MOD : a + b; }
    int sub(int a, int b) { return a - b < 0 ? a - b + MOD : a - b; }
    int mul(int a, int b) { return (a * b * 1ll) % MOD; }
    void addon(int &a, int b) { a = add(a, b); }
} using namespace calc;

int n;
std::string bra;
int a[MAXN];
std::map<int, int> f[MAXN], g[MAXN];

signed main()
{
    std::cin >> bra; n = bra.length(); bra = ' ' + bra;
    for (int i = 1; i <= n; i++) a[i] = (bra[i] == '(') ? 1 : -1, f[i][a[i]] = 1, g[i][a[i]] = 1;

    /*转移*/
    for (int i = 1; i <= n; i++) for (int j = -n; j <= n; j++) addon(f[i][j], f[i - 1][j - a[i]]);
    for (int i = n; i >= 1; i--) for (int j = -n; j <= n; j++) addon(g[i][j], g[i + 1][j - a[i]]);

    int ans = 0;
    /*统计答案*/
    for (int i = 1; i <= n; i++) {
        int res = 0;
        for (int j = ((a[i] == 1) ? -1 : 1); j <= n; j++) addon(res, mul(f[i - 1][j], g[i + 1][-j - a[i]]));
        if (a[i] == 1) addon(res, g[i + 1][-a[i]]);
        if (a[i] == -1) addon(res, f[i - 1][-a[i]]);
        addon(ans, mul(res, i));
    }
    printf("%lld", ans);

    return 0;
}

\(\rm{T2}\)

\(\rm{T1}\) 想乱了, 先去想 \(\rm{T2}\) , 回头再看 \(\rm{T1}\)
甚至 \(\rm{T2}\) 也像做过的题

很危险, 赶紧把该拿的分拿了, 不要在死磕
先不管 \(\rm{T1}\) 了

今天的策略是把后面的题暴力打了死磕 \(\rm{T1}\)

思路

这个题绝对是做过的

原来至少三位数是这样的吗

好吧那不管这道题

\(\rm{T3}\)

目前得分: \(130 \ \rm{pts}\)
虽然那 \(100\) 应该不能算

思路

首先把每一行删除一位之后结果相同的删除选择并到一起
具体的, 如果删除 \(a_i, a_j\) 对于 \(i\) 行的结果一样, 那么把 \(i, j\) 加入同一个集合, 假设第 \(i\) 行对应的操作集合为 \(\mathbb{S}_{i, k}\)

考虑 \(\rm{dp}\) , 令 \(f_{i, j}\) 表示考虑到第 \(i\) 行, 其中这一行删除的位置属于 \(j\) 集合的方案数
考虑转移

\[f_{i, j} \gets \sum_{\mathbb{S}_{i - 1, k} \cap \mathbb{S}_{i, j} \neq \varnothing} f_{i - 1, k} \]

其中并集特殊实现
复杂度 \(\mathcal{O} (n^3)\) , 完全足够了, 开打

总结

\(\rm{T1}\) 思路不够优秀, 没有意识到这一点浪费了太多时间
\(\rm{T3}, \rm{T4}\) 部分分很多, 没有意识到这一点

以后一定要对自己的水平有清楚认知, 做好策略, 然后按照时间分配打下去, 切莫死磕

标签:1.12,赛时,int,T1,后缀,rm,考虑,CW,前缀
From: https://www.cnblogs.com/YzaCsp/p/18666877

相关文章

  • 2024.11.12(spring boot创建数据库)
    前端代码UserMapper.xmlselect*fromspringboot.user<selectid="queryUserById"resultType="User"parameterType="int">select*fromspringboot.userwhereid=#{id};</select><insertid="......
  • AcWing算法基础课打卡 | 790 数的三次方根
    学习C++从娃娃抓起!记录下AcWing刷过的题目,记录每一个瞬间。附上汇总贴:AcWing算法基础课打卡|汇总【题目描述】给定一个浮点数,求它的三次方根。【输入】共一行,包含一个浮点数。【输出】共一行,包含一个浮点数,表示问题的解。注意,结果保留位小数。【输入样例】1......
  • 1.9 CW 模拟赛 T2. array
    思路简单的考虑梦梦的决策点为\(k\)时,如何使最大子段和最大化容易想到以下的分类讨论完全在\([1,2k-2]\cup[2k+1,2n]\)中包含\(C_{2k-1},C_{2k}\)中的任意一个包含\(C_{2k-1},C_{2k}\)考试的时候想到了这里,问题在于如何高效的解决计算这\(3\)......
  • 1.9 CW 模拟赛 赛时记录
    前言策略不变,继续搞看题\(4\)神秘,开骗\(\rm{T1}\)思路先考虑对于一个确定的\(a\)怎么做发现一个数能否被删除与删除的顺序无关,本质上是因为\(j,l\)并不因为操作而改变考虑到一个数能被删除,仅当其在前后缀中都不为最大值,也就是说可以\(\mathcal{O}(n)\)......
  • AcWing算法基础课打卡 | 788 逆序对的数量
    学习C++从娃娃抓起!记录下AcWing刷过的题目,记录每一个瞬间。附上汇总贴:AcWing算法基础课打卡|汇总788逆序对的数量【题目描述】给定一个长度为nnn的整数数列,请你......
  • AcWing算法基础课打卡 | 789 数的范围
    学习C++从娃娃抓起!记录下AcWing刷过的题目,记录每一个瞬间。附上汇总贴:AcWing算法基础课打卡|汇总789数的范围【题目描述】给定一个按照升序排列的长度为nnn的整......
  • 1.7 CW 模拟赛 赛时记录
    前言这次没复习直接上,无敌了还是策略+时间分配,好好考看题大样例发的有点神经的\(\rm{T1}\)什么数数题,红温了,不太看得出来的样子\(\rm{T2}\)有点神秘\(\rm{T3}\)又是数数,无语了\(\rm{T4}\)神秘首先应该是普通难度,打不了的题先跳过,先拿暴力分,不要死......
  • WebAudioContext.createPeriodicWave
    PeriodicWaveNodeWebAudioContext.createPeriodicWave(Float32Arrayreal,Float32Arrayimag,objectconstraints)小程序插件:不支持功能描述创建一个PeriodicWaveNode参数Float32Arrayreal一系列余弦术语(传统上的A项)Float32Arrayimag一系列正弦项(传统上的B项)o......
  • AcWing 799:最长连续不重复子序列 ← 双指针
    【题目来源】https://www.acwing.com/problem/content/801/【题目描述】给定一个长度为n的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。【输入格式】第一行包含整数n。第二行包含n个整数(均在0∼10^5范围内),表示整数序列。【输出格式】共一行,包含一个......
  • 01.03 CW 模拟赛 T4. ring
    前言找原题未遂了()\(\rm{HD0X}\)大佬讲了没听懂啊思路无敌了,看起来似乎很困难,不知道补不补的掉首先发现不好处理成一种简单的问题,肯定是想有哪些方法可以处理这种问题\(\rm{TJ}\)的不太看得懂你可以树状数组维护区间和,每次对于一个环暴力修改\(\mathcal{O}(s......