首页 > 其他分享 >[AGC064D] Red and Blue Chips 题解

[AGC064D] Red and Blue Chips 题解

时间:2024-07-06 17:19:49浏览次数:14  
标签:Blue pr ch int 题解 枚举 fac Chips define

题目链接

点击打开链接

题目解法

挺牛的题

这种计数本质不同的结果的题,一个很不错的切入口是判断结果的合法性

B 的总数为 \(m\)
我们把结果串先挂在第 \(m\) 个 B
考虑从后往前枚举原串(最后一个 B 不枚举),相当于我们在倒序模拟操作过程

  1. 枚举到 B,我们相当于要把后面的一个 B 的序列劈成两半,前一半挂在当前这个 B
  2. 枚举到 R,把后面任意一个 B 的序列的开头去掉一个 R

举个例子:
原串为 RBBRRB,结果串为 RRBRBB
一开始第 \(3\) 个 B 上有序列 RRBRBB
枚举到第 \(5\) 个字符 R 时,去掉第 \(3\) 个 B 开头的 R
枚举到第 \(4\) 个字符 R 时,去掉第 \(3\) 个 B 开头的 R
枚举到第 \(3\) 个字符 B 时,当前第 \(3\) 个 B 的串为 BRBB,分成 BRB(第 \(2\) 个 B 对应的串) 和 B(第 \(3\) 个 B 对应的串)
枚举到第 \(2\) 个字符 B 时,把第 \(2\) 个 B 的串分成 BRB
最后直接去掉第 \(2\) 个 B 开头的 R 即可

抽象一下这个问题:
我们把结果串 B 前的最长连续 A 的个数序列称为 \(a\)(顺序)
原串 B 前的最长连续 A 的个数序列称为 \(b\)(逆序)
那么结果串合法的充要条件是:

  1. \(\sum a_i=n-m\)
  2. 因为 \(a_1\) 是不能动的,所以把 \(a_2,...,a_n\) 从大到小排序之后,需要满足 \(\sum a_i\ge \sum b_i\)

这个问题是好计数的,具体见代码,时间复杂度是 \(O(n^2\log^2 n)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=310,P=998244353;
int n,pr[N],f[N][N],g[N][N];
char str[N];
inline void inc(int &x,int y){ x+=y;if(x>=P) x-=P;}
int fac[N],ifac[N];
int qmi(int x,int y){
    int res=1;for(;y;y>>=1){ if(y&1) res=1ll*res*x%P;x=1ll*x*x%P;}
    return res;
}
void comb(int n){
    fac[0]=1;F(i,1,n) fac[i]=1ll*fac[i-1]*i%P;
    ifac[n]=qmi(fac[n],P-2);DF(i,n-1,0) ifac[i]=1ll*ifac[i+1]*(i+1)%P;
}
int main(){
    read(n);
    comb(n);
    scanf("%s",str+1);
    int cnt=0,m=0;
    F(i,1,n){
        if(str[i]=='R') cnt++;
        else pr[++m]=cnt,cnt=0;
    }
    reverse(pr+1,pr+m+1);
    F(i,1,m) pr[i]+=pr[i-1];
    int R=n-m;
    F(i,pr[1],R) f[i][1]=1;
    DF(i,R,1){
        F(j,0,R) F(k,1,R/i+1) if(f[j][k]){
            int mxq=min((R-j)/i,m-k);
            F(q,0,mxq){
                if(j+q*i<pr[k+q]) break; 
                inc(g[j+q*i][k+q],1ll*f[j][k]*ifac[q]%P);
            }
        }
        F(j,0,R) F(k,1,R/i+1) f[j][k]=g[j][k],g[j][k]=0;
    }
    int ans=0;
    F(i,1,m) inc(ans,1ll*f[R][i]*ifac[m-i]%P);
    ans=1ll*ans*fac[m-1]%P;
    printf("%d\n",ans);
    return 0;
}

标签:Blue,pr,ch,int,题解,枚举,fac,Chips,define
From: https://www.cnblogs.com/Farmer-djx/p/18287500

相关文章

  • HT-014 Div3 扫雷 题解 [ 绿 ] [ 二维差分 ]
    分析观察到是曼哈顿距离\(\ler\)的范围可以扫到,联想到如下图形:左边是\(r=1\)可以扫到的范围,右边是\(r=2\)可以扫到的范围。于是,我们只要对这样的图形在\(1000*1000\)的格子里差分一下就好了。但这样的复杂度是\(O(nm)\)的,会死的很惨。优化不难发现这个图形是一......
  • HT-014 Div3 跳棋 题解 [ 黄 ] [ 并查集 ] [ 树型结构 ]
    分析依旧是一个连通块题。观察题面不难发现两个重要性质:一个跳棋只能以它旁边的两个跳棋为中点跳跃,且满足跳跃路线中除中点以外没有其它跳棋阻挡。只有我们的跳棋可以移动。跳棋的操作具有可逆性/对称性。第三条性质可以这么理解,就是一个跳棋跳过去之后,它还可以跳回来。......
  • [POI2015] WYC 题解
    [POI2015]WYC显然矩阵乘法发现点数和边权非常小,所以可以考虑拆点把每个点拆为\(u_1\),\(u_2\),\(u_3\),初始:\(u_1\tou_2\),\(u_2\tou_3\),每一条加边:\(u+(w-1)\timesn\tov\)因为\(k\)非常大,所以考虑倍增优化注意:答案会爆longlong,需要使用unsignedlonglong//Pro......
  • python-docx库 写入docx时中文不适配问题,中文异常问题解决办法。
    python-docx库写入docx时中文不适配问题,中文异常问题解决办法。通过以下方法可以成功将正文修改为宋体字体。这个是全文设置。fromdocx.oxml.nsimportqndoc=Document()doc.styles['Normal'].font.name=u'宋体'doc.styles['Normal']._element.rPr.rFonts.set(qn('w:......
  • ZeroMQ最全面试题解读(3万字长文)
    目录解释ZeroMQ是什么,它的主要用途是什么?ZeroMQ支持哪些通信模式?描述一下ZeroMQ中的“消息”和“消息帧”如何在C++中初始化一个ZeroMQ上下文?在ZeroMQ中,如何创建一个套接字并将其绑定到特定端口?解释什么是“管道模式”(PipePattern)说明如何使用ZeroMQ进行点对点通信Zer......
  • 题解:CF1256D Binary String Minimizing
    贪心。数据范围\(n\le10^{6}\),因此我们要用时间复杂度为\(\mathcal{O}\left(n\right)\)的算法来解决这个问题。思路从左至右扫一遍序列,如果遇到\(10\),则要将这个\(0\)交换到前面的位置。由于是字典序最小,\(0\)应该尽量在最高位。现在需要知道这个\(0\)被交换到哪......
  • 2016 CSP-J/NOIP万字长文复赛真题题解——秒杀T1 买铅笔,T2 回文日期,T3 海港,T4 魔法
    [NOIP2016普及组]买铅笔题干[NOIP2016普及组]买铅笔题目背景NOIP2016普及组T1题目描述P老师需要去商店买nnn支铅笔作为小朋友们参加NOIP的礼物。她发现......
  • 端口占用问题解决方案(Windows)
    端口占用问题解决方案(Windows)在开发和运维过程中,我们经常会遇到端口被占用的情况。这可能导致服务器启动失败或者其他服务无法正常运行。本文将介绍如何使用命令行工具来查询和解决端口占用问题。一、查询当前所有端口使用情况可以使用netstat-ano命令来查看当前所有......
  • StarRocks数据导入慢问题解决
    一、问题描述依据StarRocks官网快速开始安装教程,用dockercompose安装了starrocks,log模块从rabbitMq的队列批量获取log消息,发现队列消息有堆积,一晚上下来大概能对接4000条消息。经单元测试发现insertinto到starrocks中时间竟然相差几百倍。mysql每条insertsql执行3.5mss......
  • 题解 - 定价
    题目题目描述你如此计算一个价格\(p\)(为正整数)的荒谬程度:首先将\(p\)看做一个由数字组成的字符串(不带前导\(0\));然后,如果\(p\)的最后一个字符是\(0\),就去掉它。重复这一过程,直到\(p\)的最后一个字符不是\(0\);记\(p\)的长度为\(a\),如果此时\(p\)的最后一位是......