11.22 CW 模拟赛 赛时记录

看题#

也是把昨天的题调完 + 开大, 开局自带 15min 劣势(

还是老 Theme 用的爽

机房有人能把薄膜键盘敲出机械的声音

感觉每场都只打了弱智分, 怎么办?

A#

我咧个逆序对啊

一眼找规律 + 思维, 应该能做

B#

像是图论一类的东西, 观察一下看能不能做

不是哥们, 不给部分分?

C#

我不到啊

D#

我不到啊


话说每次都看完题正序做, 好像也没什么意义

A#

容易的, 我们可以知道数列 a 的逆序对个数, 因为 n5000 , 我们直接用 O(n2) 算法即可

注意到 k106 , 我们是有能力枚举每一个复制串的 (以下记为 p )

那么问题就简单了

考虑计算每个数在 a 数列中, 有多少个数比他大(以下设为 Bi)

那么对于第 i 次重复, 前面就会有 (i1)×(j=1nBj) 个自带逆序对, 然后对于这一次复制出来的数列 a , 再计算带来的逆序对即可

具体的, 枚举每一个复制串, 每一个复制串对答案的贡献为 (i1)×(j=1nBj)+p , 总时间复杂度 O(n2+k)

B#

也是传统不写代码, 开就完了

显然的, 我们可以先转化问题
对于无向图上的 n 个点, 点之间的边权就是 min(图上的欧氏距离的平方和,v) , 求走完所有点时经过的最小边权和

手玩样例看下有没有思路?

显然的, 对于 50pts , 状压可以解决

想到 1h 先跳过, 分数已经够多了

考虑剩下的 50pts , 注意到我们的目标是在完全图中掏一个长为 n 的环出来使得边权和最小, 显然可以状态压缩 , 由于是完全图, 状态膨胀非常快, 大概是 nn 这一级的, 这一点也不好处理, 兴许有些妙妙做法可以做, 但我今天这状态应该止步于此了, lhs 多半又 AK

其实对于后面的点, 我有一个乱搞做法, 枚举起始点, 每个点贪心的选择最近点即可, 但是正确性比较的不显然, 冬天到了也是没有什么打的欲望

考虑剪掉不需要的枝, 然而剪不掉w

顺着状压 dp 往下走
注意到每一条边 (u,v) 都可以更新 Statewithout v and with uStatewith v and with u
考虑逆向处理
我们可以知道, 对于每一个点 v , 我们可以枚举其出边权值最小, 加在一起即可
但是这里有约束条件, 注意到如果 u 已经不在集合中, 我们不能使用 (u,v)

所以我们要找出 n1 条边, 其中每个点作为终点只出现一次

然后就可以用最小生成树处理了

C#

也是大劣势, 出场多半发现其他人都有 300pts 起手, 好嘛

神秘题目, 也是不太理解, 像 dp 倒是

考虑 n1340pts , 可以 dfs 去处理, 对于每个点, 要么撤回到之前的点, 要么继续往前走, 要么留下来

有点困, 今天又要反向 rk1

稍微想拿多一点的分就需要想正解, 丢了

D#

高档暴力 60pts 可以打

对于 n=3,4,5,6 , 直接枚举即可, 判断是简单的

对于 x=1,y=1,z=1 , 直接 n2 枚举分段即可
对于 x=1,y=1,z=2 , 考虑 n2 枚举的时候加点判断?
最后一段可以是

  • 两个 1
  • 一个 2

代码#

也是留下接近 2h 来打

A#

#include <bits/stdc++.h>
#define int long long
const int MAXN = 5200;

int n, k;
int a[MAXN];

class Sol_Class
{
private:
    int p = 0;

    int App[MAXN];
    int SumB = 0;

    int Ans = 0;

public:
    /*计算数列 a 逆序对个数, 以及 B 的和*/
    void CalcP()
    {
        memset(App, 0, sizeof(App));
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j < i; j++) {
                if (a[j] > a[i]) p++;
            }
            App[a[i]]++;
        }

        // std::sort(a + 1, a + n + 1);
        for (int i = 1; i <= n; i++) {
            for (int j = a[i] + 1; j <= 5000; j++)
                SumB += App[j];
        }
    }

    /*计算答案*/
    void solve()
    {
        for (int i = 1; i <= k; i++) {
            Ans += (i - 1) * SumB + p;
        }

        printf("%lld", Ans);
    }
} Sol;

signed main()
{
#ifdef FILE_IO
    freopen("inversion.in", "r", stdin);
    freopen("inversion.out", "w", stdout);
#endif
    scanf("%lld %lld", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
    }

    Sol.CalcP();
    Sol.solve();

    return 0;
}

虽然很神经, 但是打完了, 用时 16min

B#

建边跑 dp

发现状压往里走应该就是正解, 那就把这个题放到最后去

C#

写个 dfs 即可

喵了个咪的打不出来, 丢了

D#

#include <bits/stdc++.h>
const int MAXN = 70;

int n, x, y, z;

int s[MAXN];
bool check()
{
    int Sum[MAXN];
    memset(Sum, 0, sizeof(Sum));
    for (int i = 1; i <= n; i++) Sum[i] = Sum[i - 1] + s[i];

    int Cut1 = 0;
    while(Sum[Cut1] < x) Cut1++;
    if (Sum[Cut1] != x) return false;

    int Cut2 = Cut1;
    while(Sum[Cut2] - Sum[Cut1] < y) Cut2++;
    if (Sum[Cut2] - Sum[Cut1] != y) return false;

    if (Sum[n] - Sum[Cut2] != z) return false;
    return true;
}

int Ans = 0;
void dfs(int Now)
{
    if (Now == n) {
        if (check())
            Ans++;
        return;
    }
    for (int i = 1; i <= 10; i++) {
        s[Now + 1] = i;
        dfs(Now + 1);
        s[Now + 1] = 0;
    }
}

int main()
{
#ifdef FILE_IO
    freopen("subsequence.in", "r", stdin);
    freopen("subsequence.out", "w", stdout);
#endif

    scanf("%d %d %d %d", &n, &x, &y, &z);

    if (n <= 6)
    {
        dfs(0);
        printf("%d", Ans);
    } else{
        if(z == 1)
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n && i + j < n; j++) {
                    int k = n - i - j;
                    Ans += i * j * k;
                }
            }
        else
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n && i + j < n; j++) {
                    int k = n - i - j;
                    if (k == 1) Ans += i * j * k;
                    else Ans += i * j * (k * (k - 1) / 2) + i * j * k;
                }
            }

        printf("%d", Ans);
    }

    return 0;
}

欧呦, 谢天谢地了, 30min 还要想 B , 从某种意义上来讲, 我是备战明天比赛的第一个 Man

posted @   Yorg  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示