IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> AT3871 [AGC021E] Ball Eat Chameleons -> 正文阅读

[C++知识库]AT3871 [AGC021E] Ball Eat Chameleons

https://www.luogu.com.cn/problem/AT3871

建议先做[SCOI2010]生成字符串

好了直接来分析这一题

假设红蓝球数为 R , B R,B R,B
R + B = k R+B=k R+B=k
首先一定要满足 R ≥ B R\ge B RB
如果 R ≥ B + n R\ge B+n RB+n显然随便拍就行,容易计算 ( R + B R ) \binom{R+B}{R} (RR+B?)

如果 R < B + n R < B+n R<B+n 必定是每个变色龙先吃红,再吃蓝,再吃红交替

刚好有 R ? B R-B R?B个变色龙红的比蓝的多一个,这些变色龙就不用管了(最后多吃一个 R R R就掰回去了),主要看剩下红蓝相等的

n ? ( R ? B ) n-(R-B) n?(R?B)

也就是至少要有这么多个蓝球要在红球后面

那么相当于最多只能有 B ? ( n ? ( R ? B ) ) = R ? n B-(n-(R-B))=R - n B?(n?(R?B))=R?n个蓝球在红球前面(没有被匹配)

把红球看成 + 1 +1 +1,蓝球看成 ? 1 -1 ?1,就是这个序列任意的前缀和要 > = ? ( R ? n ) >=-(R-n) >=?(R?n)

相当于是不碰线的路径计数问题

这是个经典问题,和上面那题一样

从原点出发, + 1 +1 +1表示往右上方走一格子 ( x + 1 , y + 1 ) (x+1,y+1) (x+1,y+1) ? 1 -1 ?1表示往右下走一格子 ( x ? 1 , y ? 1 ) (x-1,y-1) (x?1,y?1)
然后不能碰到 y = ? ( R ? n ) ? 1 y=-(R-n)-1 y=?(R?n)?1这条线
求方案数

只需要在第一次碰线的时候把前面那一段关于那条线对称一下

发现有 R ? n + 1 R-n+1 R?n+1个右下的变成右上的了,其他不变,于是用总的减去这些就行了

( R + B R ) ? ( R + B R + ( R ? n + 1 ) ) \binom{R+B}{R}-\binom{R+B}{R+(R-n+1)} (RR+B?)?(R+(R?n+1)R+B?)

还有一种特殊情况,当 R = B R=B R=B的时候,因为你多的蓝球没地方扔,不对,可以考虑先拿出来
一个蓝球(应为最后一个放的肯定是蓝球),然后就变得和上面那个问题一样了

code:

#include<bits/stdc++.h>
#define N 5000050
#define ll long long
#define mod 998244353
using namespace std;
ll qpow(ll x, ll y) {
    ll ret = 1;
    for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
    return ret;
}
ll fac[N], ifac[N];
int n, k;
void init(int n) {
    fac[0] = 1;
    for(int i = 1; i <= n; i ++) fac[i] = fac[i - 1] * i % mod;
    ifac[n] = qpow(fac[n], mod - 2);
    for(int i = n - 1; i >= 0; i --) ifac[i] = ifac[i + 1] * (i + 1) % mod;
}
ll C(int n, int m) {
    if(n < m || m < 0 || n < 0) return 0;
    return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
int main() {
    scanf("%d%d", &n, &k); init(max(n, k));
    if(k < n) {
        printf("0");
        return 0;
    }
    ll ans = 0;
    for(int r = 0; r <= k; r ++) {
        int b = k - r;
        if(r < b) continue;
        if(r == b) b --;
        ans = (ans + C(r + b, r)) % mod;
        if(r < n + b) ans = (ans - C(r + b, r + r - n + 1) + mod) % mod;
    }
    printf("%lld", ans);
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:33:09  更:2022-03-13 21:34:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:05:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码