• 【UOJ424】count


    题面

    UOJ

    题解

    (m>n)显然无解。

    建出这个序列的笛卡尔树(如果大小相同则取最左的点),那么一颗笛卡尔数对应且只对应一种序列。

    考虑这棵笛卡尔树的性质,就是往左儿子走它的数的大小必然减小至少(1),而往右走是不一定减一的。

    那么这棵笛卡尔树必须要满足从根往叶子节点走,向左走的次数(leq m)

    考虑这个笛卡尔树的括号序列,就是说一个点每往左走就打一个(然后回溯回来就打一个),向右儿子走则不管,注意一个点如果没有左儿子的话就直接上一个()

    (权值为(1))权值为(-1),那么这个括号序列需要满足的要求有:(0leq)前缀和(leq m)

    将这个转成格路问题,就是从((0,0))走整点到((n,n)),其中每一步只能向右或向上走一格,且不能碰到直线(A:y=x+1,B:y=x-m-1),问方案数。

    将连续碰到一条直线看作一次碰撞(例如(ABBAAB)看作(ABAB)),那么可以枚举一次碰到什么直线,容斥计数即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <tuple>
    using namespace std; 
    const int Mod = 998244353; 
    const int MAX_N = 2e5 + 5; 
    int fpow(int x, int y) { 
    	int res = 1; 
    	while (y) { 
    		if (y & 1) res = 1ll * res * x % Mod; 
    		x = 1ll * x * x % Mod; 
    		y >>= 1; 
    	} 
    	return res; 
    } 
    int N = 2e5, M, fac[MAX_N], ifc[MAX_N]; 
    int C(int n, int m) { 
    	if (n < 0 || m < 0 || n < m) return 0; 
    	else return 1ll * fac[n] * ifc[m] % Mod * ifc[n - m] % Mod; 
    } 
    int main () { 
    #ifndef ONLINE_JUDGE 
        freopen("cpp.in", "r", stdin); 
    #endif 
    	fac[0] = 1; for (int i = 1; i <= N; i++) fac[i] = 1ll * fac[i - 1] * i % Mod; 
    	ifc[N] = fpow(fac[N], Mod - 2); 
    	for (int i = N - 1; ~i; i--) ifc[i] = 1ll * ifc[i + 1] * (i + 1) % Mod; 
    	cin >> N >> M;
    	if (M > N) return puts("0") & 0; 
    	int x = N, y = N, ans = C(x + y, x); 
    	while (x >= 0 && y >= 0) { 
    		tie(x, y) = make_tuple(y - 1, x + 1), ans = (ans - C(x + y, x) + Mod) % Mod; 
    		tie(x, y) = make_tuple(y + M + 1, x - M - 1), ans = (ans + C(x + y, x)) % Mod; 
    	} 
    	x = y = N;
    	while (x >= 0 && y >= 0) { 
    		tie(x, y) = make_tuple(y + M + 1, x - M - 1), ans = (ans - C(x + y, x) + Mod) % Mod; 
    		tie(x, y) = make_tuple(y - 1, x + 1), ans = (ans + C(x + y, x)) % Mod; 
    	} 
    	printf("%d
    ", ans); 
        return 0; 
    } 
    
  • 相关阅读:
    (转载)5分钟安装Linux系统到U盘
    (原创)LAMP搭建之二:apache配置文件详解(中英文对照版)
    (原创)LAMP搭建之一:图解如何安装并检查LAMP
    OpenGL-渲染管线的流程(有图有真相)
    判断点在直线上
    使用QT开发GoogleMap瓦片显示和下载工具
    转:PCL+VS2010环境配置
    error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:值“0”不匹配值“2”
    An error occurred during the installation of assembly 'Microsoft.VC90.ATL or 'Microsoft.VC80.ATL'
    如何确定VS编译器版本
  • 原文地址:https://www.cnblogs.com/heyujun/p/12202399.html
Copyright © 2020-2023  润新知