题目描述 Description

精灵心目中亘古永恒的能量核心崩溃的那一刻,Bzeroth 大陆的每个精灵都明白,他们的家园已经到了最后的时刻。
就在这危难关头,诸神天降神谕,传下最终兵器——潘少拉魔盒。然而当精灵们准备打开魔盒时,魔盒的守护灵出现在精灵们面前:“如果你们想要拯救世界,必须要先解决这个困难的问题:定义一个 N 阶数列 A 为神奇数列当且仅当对所有2≤i≤N−1 ,都有 Ai−1+Ai+1≥2×Ai。现在有一个N阶正整数列B ,请计算将 B 数列均匀随机打乱之后,得到的数列是神奇数列的概率 P 。你只需要输出P×(N!)mod998244353 的结果即可。(显然 P×(N!) 一定是个整数)。”

输入描述 Input Description

第一行为 1 个正整数 N。
第二行为 N 个正整数 Ai。

输出描述 Output Description

输出 P×(N!)mod998244353 的结果。

样例输入 Sample Input

4
1 2 1 3

样例输出 Sample Output

8

数据范围及提示 Data Size & Hint

对于 50%的数据:3 ≤ N ≤ 10。
对于 80%的数据:3 ≤ N ≤ 20。
对于 100%的数据:3 ≤ N ≤ 40,1≤Ai≤109 。


容易知道,这个题实际上是想让我们求给定的集合能够拼成多少个神奇数列。

经过推一波式子,我们可以知道a[i+1]-a[i]>=a[i]-a[i-1],所以它的差分序列单调递增,即其为一个下凸函数。。

因此,对于一个神奇数列,满足它一定是一个下凸函数。

考虑在这个函数上进行dp:

对于一个区间dp[i][k],表示区间最左端取值为a[i],最右端取值为a[k],则进行转移时每次往左端或右端放入一个点。

但是由于刚才的式子,我们必须记录端点之前的位置的取值,所以我们用dp[i][j][k][l]表示某个下凸函数的一段区间最左端取值为a[i],a[j],最右端取值为a[l],a[k]的神奇序列个数。

考虑将原来的集合排序,所以易知下凸函数的顶点一定是整个集合的最小值。

由此,我们每次考虑放入一个新值a[pos]满足pos=max(i,k)+1,原因是排好序的序列单调递增,又因为a[i],a[k]一定含有当前区间值最大的点(因为是下凸函数),所以我们只需要取二者下标最大值+1作为新值下标。所以可以用刚才的方法检验是否答案合法。

上代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
#define mem(a,b) memset(a,b,sizeof(a))
typedef pair<int,int> PII;
typedef pair<int,PII> PIP;
const int MOD=,maxn=;
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a[maxn],sum=,jc[maxn],dp[maxn][maxn][maxn][maxn],ans;
int main()
{
n=read();
jc[]=;
for(int i=;i<=n;i++)a[i]=read(),jc[i]=((LL)jc[i-]*(LL)i)%MOD;//阶乘预处理
sort(a+,a+n+);
for(int i=;i<=n;i++)
{
if(a[i]!=a[i-])break;
sum++;
}//取出区间最小值
for(int i=sum+;i<=n;i++)a[i-sum+]=a[i];//把其它最小值扔到后面
dp[][][][]=;
n=n-sum+;//去掉与最小值相同的值
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
for(int k=;k<=n;k++)
for(int l=;l<k;l++)
{
int pos=max(i,k)+;//找到新加入的数
if(pos==n+){ans=(ans+dp[i][j][k][l])%MOD;continue;}//如果整个下凸函数已经构成了长度为n的区间
if(*a[i]<=a[pos]+a[j] || i==)dp[pos][i][k][l]=(dp[pos][i][k][l]+dp[i][j][k][l])%MOD;//检查i端是否合法
if(*a[k]<=a[pos]+a[l] || k==)dp[i][j][pos][k]=(dp[i][j][pos][k]+dp[i][j][k][l])%MOD;//检查k端是否合法
}
printf("%d\n",((LL)ans*(LL)jc[sum])%MOD);//因为最小值一共有sum个取值,所以这sum个取值进行全排列再乘以答案即可
return ;
}

2019.10.24 CSP%你赛第二场d1t3的更多相关文章

  1. 2019.10.26 CSP%您赛第三场

    \(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(ligh ...

  2. 2019.10.28 CSP%您赛第四场t3

    我写不动前两个了. 原谅一下. ____________________________________________________________________________________ ...

  3. 2019.10.29 CSP%您赛第四场t2

    我太菜了我竟然不会分层图最短路 ____________________________________________________________________________________ ...

  4. Contest1592 - 2018-2019赛季多校联合新生训练赛第二场(部分题解)

    Contest1592 - 2018-2019赛季多校联合新生训练赛第二场 D 10248 修建高楼(模拟优化) H 10252 组装玩具(贪心+二分) D 传送门 题干 题目描述 C 市有一条东西走 ...

  5. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  6. 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)

    以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...

  7. 2019 计蒜之道 初赛 第二场 B. 百度AI小课堂-上升子序列(简单) ( 实现)

    题目背景 ​91029102 年 99 月 22 日,百度在 X 市 XX 中学举办的第一场 AI 知识小课堂大获好评!同学们对矩阵的掌握非常棒. 今天的 AI 知识小课堂的第二场开讲啦.本场 AI ...

  8. 2019杭电多校赛第九场 Rikka with Mista

    Problem Description Rikka is a fervent fan of JoJo's Bizarre Adventure. As the last episode of Golde ...

  9. 2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型

    题意: 有n个士兵,你可以选择让它成为战士还是法师. 有m对关系,u和v 如果同时为战士那么你可以获得a的权值 如果同时为法师,你可以获得c的权值, 如果一个为战士一个是法师,你可以获得b的权值 问你 ...

随机推荐

  1. mybatis源码专题(1)--------复习jdbc操作,编译mybatis源码,准备为你的简历加分吧

    本文是作者原创,版权归作者所有.若要转载,请注明出处.文章中若有错误和疏漏之处,还请各位大佬不吝指出,谢谢大家. 1.mybatis的底层是jdbc操作,我们来回顾一下,如下  运行以后的结果如下图: ...

  2. jvm 内存溢出

    堆内存溢出 堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出OutOfMemory:Java heap space 永久代溢出 类的一些信息,如类名.访 ...

  3. 多事之秋-最近在阿里云上遇到的问题:负载均衡失灵、服务器 CPU 100%、被 DDoS 攻击

    昨天 22:00~22:30 左右与 23:30~00:30 左右,有1台服役多年的阿里云负载均衡突然失灵,造成通过这台负载均衡访问博客站点的用户遭遇 502, 503, 504 ,由此给您带来麻烦, ...

  4. 【linux】【jdk】jdk8.0安装

    系统环境:Centos7 一.下载jdk8.0 jdk官方网站:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downlo ...

  5. kubernetes实战(二十六):kubeadm 安装 高可用 k8s v1.16.x dashboard 2.x

    1.基本配置 基本配置.内核升级.基本服务安装参考https://www.cnblogs.com/dukuan/p/10278637.html,或者参考<再也不踩坑的Kubernetes实战指南 ...

  6. 第八届蓝桥杯java b组第三题

    标题:承压计算 X星球的高科技实验室中整齐地堆放着某批珍贵金属原料. 每块金属原料的外形.尺寸完全一致,但重量不同.金属材料被严格地堆放成金字塔形. 7                         ...

  7. Maven 梳理-自动创建Maven项目(非web)

    mvn archetype:create和mvn archetype:generate create is deprecated in maven 3.0.5 and beyond,在maven3.0 ...

  8. springboot + thymeleaf静态资源访问404

    在使用springboot 和thtmeleaf开发时引用静态资源404,静态资源结如下: index.html文件: <!DOCTYPE html> <html xmlns:th= ...

  9. windows 安装gitbook并使用gitbook editor可视化工具

    GitBook是一个基于 Node.js 的命令行工具,可使用 Github/Git 和 Markdown 来制作精美的电子书. 一.官网下载nodejs直接安装 传送门,安装完成后如下: 可以看到n ...

  10. JS 生成唯一值UUID

    md5加密new Date()生成的值可能不是唯一的,另一种生成唯一值的方式: getUID: function() { // 获取唯一值 return 'xxxxxxxx-xxxx-4xxx-yxx ...