zoukankan      html  css  js  c++  java
  • [清华集训2016] 你的生命已如风中残烛

    考虑我们对所有数都减一,那么我们求的就是这个每个前缀和都是大于等于0的数列数量。
    那么有这么一个定理:

    如果有一个数列其和为1,那么在他的循环移位上有且仅有一个满足前缀和全大于等于0

    那么我们发现这个原题是和为 (0) ,那么我们需要找到一个可行的方案放入一个1,且其一定是循环移位的第一个数,即没有数比他大,所以我们直接取反,再把他这个1加在这个前面。

    那我们考虑圆排列,那么就是((m + 1 - 1)! = (m)!),考虑第一个(1)(m - n + 1) 个,即有这个 ( (m - n + 1)!)排列,因为是多加了一个所以其实多算了 ((m - n + 1))

    #include<iostream>
    #include<cstdio>
    #define ll long long 
    #define N 50
    #define mod 998244353
    
    ll num[N],m;
    ll n;
    
    int main(){
    	scanf("%lld",&n);
    	for(int i = 1;i <= n;++i)
    	scanf("%lld",&num[i]),m += num[i];
    	ll s = 1;
    	for(int i = 1;i <= m;++i)
    	if(i != (m - n + 1))
    	s = (s * i % mod) % mod;
    	std::cout<<s<<std::endl;
    }
    
  • 相关阅读:
    MySQL重置密码
    linux下自动备份脚本并上传到ftp服务器
    nginx配置
    WIFI防蹭网
    无线路由知识
    009汇编环境搭建
    008 计算机不会加法
    007计算机不会做加法
    006源码反码补码
    005有符号数和无符号数
  • 原文地址:https://www.cnblogs.com/dixiao/p/15264849.html
Copyright © 2011-2022 走看看