首页 > 其他分享 >「解题报告」ARC128D Neq Neq

「解题报告」ARC128D Neq Neq

时间:2023-03-20 19:35:51浏览次数:48  
标签:ARC128D 删除 int len 解题 MAXN 一段 Neq

我果然还是适合做这种简单数数,难的我根本不会做,哈哈!

首先我们发现,如果有两个完全相同的相邻的数,那么这两个数中的每一个数都不能够被删除,那么这实际上把整个序列分成了若干段,最后的答案就是每一段的答案的乘积。

现在考虑没有相邻相同的数。观察样例,可以发现形如 abab 的形式,中间的两个数不能够被同时删除。

更进一步,假如整个段形如 ababababab...,那么发现被删除的数的限制为不能够相邻。在一段数中选取若干个不相邻的数,这个简单 DP 就能得出方案数,实际上是斐波那契数。

那么考虑不完全形如这样的数,假设段为 xababababy,那么我们发现,中间这一段我们是可以删除一个前缀和一个后缀的。那么我们考虑将这一段划分成若干个 ababab 段,每相邻两端有一个公共的数。那么我们发现,假如每一段的两端的删除情况固定了,中间的删除情况是容易计算出方案数的。

那么我们就可以设一个简单的 DP,\(f_{i, 0/1}\) 表示考虑到第 \(i\) 段,这一段与上一段的交点是否被删除,直接 DP 即可。初始 \(f_{0,0}=1\),答案为 \(f_{m, 0}\),因为第一个数和最后一个数一定不能被删除。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005, P = 998244353;
int n, a[MAXN];
int f[MAXN];
int g[MAXN][2];
int c(int len, int a, int b) {
    if (a == 0 && b == 0) {
        return f[len - 2];
    } else if (a == 1 && b == 1) {
        int ans = 1 + len - 2;
        for (int i = 0; i <= len - 4; i++) {
            ans = (ans + 1ll * f[i] * (len - 3 - i)) % P;
        }
        return ans;
    } else {
        int ans = 1;
        for (int i = 0; i <= len - 3; i++) {
            ans = (ans + f[i]) % P;
        }
        return ans;
    }
}
int solve(int l, int r) {
    vector<int> t;
    for (int i = l + 1, len = 2; i <= r; i++, len++) {
        if (i == r || a[i - 1] != a[i + 1]) {
            t.push_back(len);
            len = 1;
        }
    }
    int m = t.size();
    g[0][0] = 1;
    for (int i = 1; i <= m; i++) {
        g[i][0] = g[i][1] = 0;
        for (int a = 0; a <= 1; a++) {
            for (int b = 0; b <= 1; b++) {
                g[i][b] = (g[i][b] + 1ll * g[i - 1][a] * c(t[i - 1], a, b)) % P;
            }
        }
    }
    return g[m][0];
}
int main() {
    scanf("%d", &n);
    f[0] = 1, f[1] = 2;
    for (int i = 2; i <= n; i++)
        f[i] = (f[i - 1] + f[i - 2]) % P;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    int l = 1;
    int ans = 1;
    for (int i = 1; i <= n; i++) {
        if (i == n || a[i] == a[i + 1]) {
            ans = 1ll * ans * solve(l, i) % P;
            l = i + 1;
        }
    }
    printf("%d\n", ans);
    return 0;
}

标签:ARC128D,删除,int,len,解题,MAXN,一段,Neq
From: https://www.cnblogs.com/apjifengc/p/17237436.html

相关文章

  • cf1774f解题报告
    MagicianandPigs分析一下三个操作分别干了些什么新添一只猪使血量为\(x\)的猪血量变为\(\max(x-v,0)\)设前面操作后猪总共会受到\(s\)的伤害,复制一只血量为\(......
  • 「解题报告」ARC130E Increasing Minimum
    想法大概差不多,但是确实不知道咋维护(考虑每次删最小值的过程,我们相当于先删掉所有最小值\(=1\)的位置,然后删所有最小值\(=2\)的位置,依次类推。那么我们可以将删除的......
  • 「解题报告」ARC132F Takahashi The Strongest
    不会FWT的真实。需要重写篇FWT博客。考虑Takahashi获胜当且仅当Aoki和Snuke选的相同,Takahashi选的是它的下一个。至少有一个相等,可以容斥为所有的都不相等。......
  • 「解题报告」ARC132E Paw
    好简单的题,但是我没想到咋做,我一上来就想把贡献拆开,然后推出了一个根本无法化简的式子,哈哈。仔细考虑一下,发现最后的形式一定是有一段没有被覆盖过,其它的都覆盖过,即形如<......
  • 「解题报告」ARC154F Dice Game
    看起来就多项式,跟概率有关就上概率生成函数吧。考虑类似于FlipCells的套路,设\(F(x)\)为翻出所有的生成函数,\(G(x)\)为第一次翻出所有的生成函数,\(H(x)\)是翻出后任......
  • Vjudge 3.14 训练解题报告
    比赛传送门\(\color{white}{password:3.1415926}\)A.Fibonacci-ish题意:定义一个序列为“Fibonacci-ish”的,当且仅当对任意\(2<i\len,a_i=a_{i-1}+a_{i-2}\)。给定......
  • # 92 -「java 」 100-执行速度 - 三步『截取子链表- 递归反转- 拼接』 解题的实现思路
    Tags中等递归链表java 题目链接:92.反转链表II 解题思路[截取子链表+反转+拼接]:以1->2->3->4->5,m=2,n=4为例:【截取】定位到需要反......
  • 剑指 Offer 68 - II. 二叉树的最近公共祖先(java解题)
    (剑指Offer68-II.二叉树的最近公共祖先(java解题))1.题目给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T......
  • CF1804 解题笔记
    赛时战况,血压飙升,成功跳崖!A随便算一下就好了。#include<bits/stdc++.h>#defineILinline#defineregregisterILintread(){regintx=0;regcharch=get......
  • 「解题报告」ARC158D Equation
    好神仙的题。考虑形如\(F(x,y,z)=x^i+y^i+z^i\)的函数有一个性质:\(F(tx,ty,tz)=t^iF(x,y,z)\)。原式要求\((x+y+z)(x^n+y^n+z^n)(x^{2n}+y^{2n}+z^{2n......