首页 > 其他分享 >2024杭电多校第7场

2024杭电多校第7场

时间:2024-08-10 22:38:12浏览次数:8  
标签:杭电多校 int mo mid 2024 num ans ll

7

1007 创作乐曲 (hdu7511

妙妙dp题,赛时wyq一眼丁真、发现可以线段树优化dp,可惜我们没推出关键性质,最后TLE遗憾离场。

在每个最优子乐曲中,音符 \(i\) 的后继音符只有两种可能:\(a[p] - a[i] \leq k\) 中距离 \(i\) 最近的 \(p\),或者 \(a[i] - a[q] \leq k\) 中距离 \(i\) 最近的 \(q\). 采用反证法,若 \(i\) 的后继是其他音符 \(j\),由 \(\mid a[j] - a[i]\mid\space\leq k\),\(a[p]\) 与 \(a[q]\) 中至少其一可放在 \(i\) 与 \(j\) 间,即其他情况不是最优解。

查询距 \(i\) 最近的合法后继结点 \(p,q,\) 可使用线段树优化时间复杂度。建立 \(1\) 至 \(m\) 的权值线段树,维护每个音符的下标,加入新的音符 \(i\) 即 \(a[i]\) 位置赋值为 \(i\),查询 \(p,q\) 即查询 \(l = a[i] - k,\space r = a[i]\) 或 \(l = a[i],\space r = a[i] + k\) 的区间最小值;注意由于权值范围过大,线段树需要动态开点。预处理所有 \(p,q,\) 询问时即可 \(O(n)\) 计算最优子乐曲。

线段树代码:

int num[M], ls[M] = {0}, rs[M] = {0}, cnt;
void update(int i, ll l, ll r, ll q, int x) {
    num[i] = x;
    if(l == r) return;
    ll mid = (l + r) / 2;
    if(q <= mid) {
        if(!ls[i]) ls[i] = ++cnt;
        update(ls[i], l, mid, q, x);
    } else {
        if(!rs[i]) rs[i] = ++cnt;
        update(rs[i], mid + 1, r, q, x);
    }
}
int query(int i, ll l, ll r, ll ql, ll qr) {
    if(ql <= l && qr >= r) return num[i];
    ll mid = (l + r) / 2;
    int ans = n + 1;
    if(ql <= mid) ans = min(ans, query(ls[i], l, mid, ql, qr));
    if(qr > mid) ans = min(ans, query(rs[i], mid + 1, r, ql, qr));
    return ans;
}

main函数内主要代码:

    cnt = 1;
    num[0] = num[1] = n + 1; // num[0] = n + 1,防止查询时最小值取为0
    for(int i = n; i; i--) {
        nex1[i] = query(1, 1, m, max(1ll, a[i] - k), a[i]);
        nex2[i] = query(1, 1, m, a[i], min(a[i] + k, m));
        update(1, 1, m, a[i], i); // 先查询再加点
    }
    int q;
    scanf("%d", &q);
    while(q--) {
        int l, r;
        scanf("%d%d", &l, &r);
        for(int i = l; i <= r; i++) {
            dp[i] = i - l;
        }
        for(int i = l; i <= r; i++) {
            dp[nex1[i]] = min(dp[nex1[i]], dp[i] + nex1[i] - i - 1);
            dp[nex2[i]] = min(dp[nex2[i]], dp[i] + nex2[i] - i - 1);
        }
        int ans = n + 1;
        for(int i = l; i <= r; i++) {
            ans = min(ans, dp[i] + r - i);
        }
        printf("%d\n", ans);
    }

1008 循环图 (hdu7512

计数题,考虑dp递推计算,发现dp方程已确定的情况下需要最多 \(10^{18}\) 次转移,且 \(n\leq 100\),可使用矩阵快速幂优化dp,分别对区间左右端点计数,最终答案即 \(ans[r] - ans[l - 1]\). 设计转移矩阵,对于 \(x\) 指向 \(y\) 的一条边,\(y\leq n\) 时在本周期内转移、可以与其他路径累计,\(y > n\) 时则只能计算一次,按节点编号依次处理可避免遗漏;\(ans[x]\) 为节点 \(1\) 至 \(x\) 方案数之和,因此在转移矩阵中添加第 \(n + 1\) 维,对前 \(n\) 维的结果求和,再令 \(a[n + 1][n + 1] = 1\),即可在快速幂过程中维护答案。初值行向量即节点 \(1\) 至 \(n\) 的方案数,与转移矩阵同理计算;对于最后不足 \(n\) 个节点的答案可暴力统计。

主要代码:

    // 转移矩阵
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            if(y[j] == i + n) {
                b[x[j]][i] += w[j];
                if(b[x[j]][i] >= mo) b[x[j]][i] -= mo;
            } else if(y[j] == i) {
                for(int k = 1; k <= n; k++) {
                    b[k][i] += b[k][x[j]] * w[j] % mo;
                    if(b[k][i] >= mo) b[k][i] -= mo;
                }
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            b[i][n + 1] += b[i][j];
            if(b[i][n + 1] >= mo) b[i][n + 1] -= mo;
        }
    }
    b[n + 1][n + 1] = 1;
    equal(qwq, b); // equal用于赋值,似乎库函数里有赋值函数但我忘了)
    fpm(b, (l - 1) / n); // 快速幂
    fpm(qwq, (r - 1) / n);
    // 初始向量
    for(int i = 1; i <= n + 1; i++) sl[i] = 0;
    sl[1] = sr[1] = 1;
    for(int i = 2; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            if(y[j] == i) {
                sl[i] += sl[x[j]] * w[j] % mo;
                if(sl[i] >= mo) sl[i] -= mo;
            }
        }
        sr[i] = sl[i];
    }
    for(int i = 1; i <= n; i++) {
        sl[n + 1] += sl[i];
        if(sl[n + 1] >= mo) sl[n + 1] -= mo;
    }
    sr[n + 1] = sl[n + 1];
    mul(sl, b); // 矩阵乘
    mul(sr, qwq);
    // 统计答案,暴力处理边界
    ll ans = (sr[n + 1] - sl[n + 1] + mo) % mo;
    int cur = (l - 1) % n + 1;
    for(int i = cur; i <= n; i++) {
        ans += sl[i];
        if(ans >= mo) ans -= mo;
    }
    cur = (r - 1) % n + 1;
    for(int i = cur + 1; i <= n; i++) {
        ans += mo - sr[i];
        if(ans >= mo) ans -= mo;
    }
    printf("%lld\n", ans);

另有:一开始转移矩阵似乎写错了,想参考std却发现它自己都过不了样例,不好评价()最后找xht要了代码才AC,感谢大佬队友orz

标签:杭电多校,int,mo,mid,2024,num,ans,ll
From: https://www.cnblogs.com/meowqwq/p/18352516

相关文章

  • 2024 Aug
    ABC366[ProblemA]Election2有\(N\)个人投票选举,两位候选人Takahashi与Aoki分别获得\(T\)票与\(A\)票,请问此时能否确定谁将赢得选举?\(0\leqT,A,T+A\leqN\leq99\),且\(N\)为奇数。设\(M=\dfrac{N+1}{2}\),则判断\(T,A\)是否有一个大于等于\(M\)即可。[......
  • [考试记录] 2024.8.10 csp-s 模拟赛18
    80+20+0+70=170第三题应该有10分暴力的,但我没打。T1星际旅行题面翻译总共有n个节点,m条路径,要求其中m-2条路径走两遍,剩下2条路径仅走一遍,问不同的路径总数有多少,如果仅走一遍的两条边不同则将这两条路径视为不同。样例#1样例输入#15412131415样例输......
  • 2024护网必看!日薪一千!怎么才能搞定(附零基础学习资料)
    前言你听说过护网吗?就是那个日薪1000——20000,食宿全包,干一个月顶半年,公安部牵头,用来评估企事业单位网络安全的活动!是不是有很多小伙伴已经心动了?要不我展开说说什么是护网行动?护网行动是一项由公安部牵头的,以检测企事业单位的网络安全防护能力为目的,针对全国范围......
  • 矢量图形设计软件:Illustrator 2024(AI)中文激活版(附安装包)
    一、简介AdobeIllustrator是一款专业的矢量图形编辑软件,主要用于:图形设计:包括标志设计、图标设计、插画创作、海报设计等。排版印刷:用于制作宣传册、书籍排版、名片等需要高质量输出的印刷品。网页设计元素:创建适合网页使用的矢量图形元素和界面设计。艺术创作:许多艺术家利......
  • Adobe Illustrator 2024 (macOS, Windows) - 矢量绘图下载
    一、AI软件简介AI(AdobeIllustrator)是一款广泛应用于图形设计、插画制作、标志设计等领域的专业矢量图形编辑软件。它以其强大的功能和灵活性,成为设计师们的重要工具之一。AI软件可以创建高质量的矢量图形,这些图形可以无限放大而不会失真。它提供了丰富的绘图工具、字体处......
  • 2024比赛wp合集
    记录一下最近比赛的wp吧D^3CTFd3note没有限制idx范围,越界任意读写,读malloc地址泄露libc,网上写systemfromExcalibur2import*proc('./pwn')lib('./libc.so.6')el('./pwn')default('h')defadd(idx,size,content):sl(b"276")sl(s......
  • 2024最新版PyCharm下载安装详细教程,Python环境配置和使用指南,零基础保姆级教程
    一、简介PyCharm是一款PythonIDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如,调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等等。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业Web开发。Pytho......
  • 2024杭电多校第七场
    1004如果r2>2r1且树的直径>2r1,则逃跑方总能逃跑否则攻击方肯定能一步步把其逼到叶子节点#include<bits/stdc++.h>usingnamespacestd;constintN=1e5;intn,s,r1,r2;vector<int>ver[N+5];inlineintread(){intx=0;boolf=1;charch=getchar();for(;ch<'0......
  • 东芝新小黑移动硬盘数据被格式化如何恢复(2024年8月版)
    在数字化时代,数据已成为我们生活和工作中不可或缺的一部分。东芝新小黑移动硬盘,以其便携性和大容量,成为许多用户存储重要数据的首选。然而,当这些宝贵的数据因意外格式化而面临丢失的风险时,我们该如何应对?本文将深入探讨东芝新小黑移动硬盘数据被格式化后的恢复方法,希望帮助用户......
  • NOI 2024
    Day1T1集合(set)容易发现两个序列等价当且仅当,所有数字在序列中出现位置的集合构成集族相等。考虑哈希,对于一个集合\(S\),令它的哈希值为\(f(S)=(\sum\limits_{x\inS}B^x)\modP\),上述条件只需做两遍哈希即可满足。使用莫队维护所有哈希值,时间复杂度\(O(q\sqrtn\lo......