现在很痛苦,等过阵子回头看看,会发现其实那都不算事。

【题目描述】
定义一个排列 a 的价值为满足|a[i]-i|<=1 的 i 的数量。
给出三个正整数 n,m,p,求出长度为 n 且价值恰好为 m 的排列的个数对 p 取
模的结果。
【输入描述】
第一行两个正整数 T,p,T 为数据组数,p 为模数。
接下来 T 行,每行两个正整数 n,m。
【输出描述】
T 行,每行一个非负数,表示答案。
【输入样例】
5 1887415157
3 1
3 2
3 3
50 10
1500 200
【输出样例】
1
2
3
621655247
825984474
【数据范围】
10%的数据:n<=10
30%的数据:n<=15
50%的数据:n<=200
另有 10%的数据:m=1
另有 10%的数据:m=n-1
100%的数据:1<=T,n,m<=2000,2<=p<=10^12


题意:
定义一个排列 a 的价值为满足|a[i]-i|<=1 的 i 的数量。
给出三个正整数 n,m,p,求出长度为 n 且价值恰好为 m 的排列的个数对 p 取模的结果。
T组询问,p事先给出。

题解:
因为n,m <= 2000,而且p是事先给出的,所以我们可以一次性预处理出n,m <= 2000的答案。

考虑一个长度为i的排列如何变成长度为i+1的排列。
一种情况是我在它末尾加入了一个数i+1,另一种情况是我用i+1替换掉了原来排列中的一个数,然后把被换掉的数放到排列的末尾。
那么,这个排列权值的变化就是:
第一种情况:在它末尾加入了一个数i+1,权值+1。
第二种情况:用i+1替换掉一个数,权值 += 加的贡献 - 换掉的数的贡献。

在DP当中,我们只需要考虑替换掉的数是否是i,以及i是否在位置i/i-1即可。总共有5种本质不同的状态,分类讨论转移即可。
复杂度O(nm)。


#include<bits/stdc++.h>
using namespace std; typedef long long LL; const int N=; int q,n,m,u,v;
LL p,ans,f[N][N][],x; int rd(){
int re=,f=;char c=getchar();
while ((c<'')||(c>'')) {if (c=='-') f=-f;c=getchar();}
while ((c>='')&&(c<='')) {re=re*+c-'';c=getchar();}
return re*f;
} int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
cin>>q>>p;
memset(f,,sizeof(f));
f[][][]=1ll;
f[][][]=1ll;f[][][]=1ll; n=;
for (int i=;i<n;++i)
for (int j=;j<=n;++j){
for (int k=;k<=;++k){
x=f[i+][j+][]+f[i][j][k];
x=(x<p)?x:(x-p);
f[i+][j+][]=x;
u=j+((k%)==);
v=+(k!=);
x=f[i+][u][v]+f[i][j][k];
x=(x<p)?x:(x-p);
f[i+][u][v]=x;
} if (f[i][j][]>0ll){
f[i+][j-][]=(f[i+][j-][]+f[i][j][]*(LL)(j-))%p;
f[i+][j][]=(f[i+][j][]+f[i][j][]*(LL)(i-j))%p;
}
if (f[i][j][]>0ll){
x=f[i+][j][]+f[i][j][];
x=(x<p)?x:(x-p);
f[i+][j][]=x;
f[i+][j-][]=(f[i+][j-][]+f[i][j][]*(LL)(j-))%p;
f[i+][j][]=(f[i+][j][]+f[i][j][]*(LL)(i-j))%p;
}
if (f[i][j][]>0ll){
x=f[i+][j][]+f[i][j][];
x=(x<p)?x:(x-p);
f[i+][j][]=x;
f[i+][j-][]=(f[i+][j-][]+f[i][j][]*(LL)(j-))%p;
f[i+][j][]=(f[i+][j][]+f[i][j][]*(LL)(i-j-))%p;
}
if (f[i][j][]>0ll){
x=f[i+][j+][]+f[i][j][];
x=(x<p)?x:(x-p);
f[i+][j+][]=x;
f[i+][j-][]=(f[i+][j-][]+f[i][j][]*(LL)(j-))%p;
f[i+][j][]=(f[i+][j][]+f[i][j][]*(LL)(i-j-))%p;
}
if (f[i][j][]>0ll){
x=f[i+][j+][]+f[i][j][];
x=(x<p)?x:(x-p);
f[i+][j+][]=x;
if (j>) f[i+][j-][]=(f[i+][j-][]+f[i][j][]*(LL)(j))%p;
f[i+][j][]=(f[i+][j][]+f[i][j][]*(LL)(i-j-))%p;
}
} for (;q>;--q){
cin>>n>>m;
ans=(f[n][m][]+f[n][m][]+f[n][m][]+f[n][m][]+f[n][m][])%p;
cout<<ans<<'\n';
}
return ;
}

C 题解———2019.10.16的更多相关文章

  1. A 题解————2019.10.16

    [题目描述] 对于给定的一个正整数n, 判断n是否能分成若干个正整数之和 (可以重复) ,其中每个正整数都能表示成两个质数乘积. [输入描述]第一行一个正整数 q,表示询问组数.接下来 q 行,每行一 ...

  2. B 题解————2019.10.16

    相信他说的话,但不要当真 [题目描述]有一个长度为 n 的自然数序列 a,要求将这个序列恰好分成至少 m 个连续子段. 每个子段的价值为该子段的所有数的按位异或.要使所有子段的价值按位与的结果最大,输 ...

  3. 2019.10.16&17小结

    话说也蛮久没写小结了,主要这两次考试失分严重,还是总结下吧. 10.16 T1 小奇挖矿2 100/0 [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市 ...

  4. @CSP模拟2019.10.16 - T3@ 垃圾分类

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 为了保护环境,p6pou建设了一个垃圾分类器. 垃圾分类器是一个 ...

  5. js第二次作业——2019.10.16

    第一题:完成省城市的三级联动(包括湖南省),附代码和效果图. 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 </head> ...

  6. Fiborial 题解——2019.10.14

    一看到这个题 就感觉...cao,, 什么东西...??! 然后就开始暴力求Fn 然鹅我并不会写高精(我太菜了) 只能求到大概10左右 在吧Fn给质因数分解 求出其因子个数 妄图找到什么有关的规律 但 ...

  7. 忍者钩爪 ( ninja) 题解———2019.10.19

    可以到这里测..嘿嘿嘿 题目: [问题 描述 ] 小 Q 是一名酷爱钩爪的忍者, 最喜欢飞檐走壁的感觉, 有一天小 Q 发现一个练习使用钩 爪的好地方,决定在这里大显身手. 场景的天花板可以被描述为一 ...

  8. T1 :最小值(min)题解 ——2019.10.15

    思路: 对于 % 30 的数据,可以想到一个 Dp 方程: 其中dp[i]表示分割[1,i]的最大答案 代码: #include<cstdio> #include<cstring&g ...

  9. 背水一战 Windows 10 (16) - 动画: ThemeAnimation(主题动画)

    [源码下载] 背水一战 Windows 10 (16) - 动画: ThemeAnimation(主题动画) 作者:webabcd 介绍背水一战 Windows 10 之 动画 PopInThemeA ...

随机推荐

  1. html。PROGRESS进度条使用测试

    效果图 : 代码: ----------------------------------- //本文来自:https://www.cnblogs.com/java2sap/p/11199126.htm ...

  2. 【Oracle】重做undo表空间

    重做undo表空间 场景: alert日志,报了如下错误: [oraprod@arpinfo bdump]$ tail -f alert_PROD.log Errors in file /ora115 ...

  3. Ansible15:文件管理模块及Jinja2过滤器

    目录 常用文件管理模块 1. file 2. synchronize 3. copy 4. fetch 5. lineinfile 6. stat 7. blockinfile Jinja2模板管理 ...

  4. ABA问题的产生及解决

    什么是ABA问题 在CAS算法中,需要取出内存中某时刻的数据(由用户完成),在下一时刻比较并交换(CPU保证原子操作),这个时间差会导致数据的变化. 1.线程1从内存位置V中取出A2.线程2从内存位置 ...

  5. Go语言http包简易入门

    说道go语言web编程,必不可少的会使用到net/http包.go语言将web开发需要使用到的很多内容都放在了标准库中——net/http. 如何写一个简单的web程序很容易.如下: package ...

  6. js联动三级

    自己研究三级加看网上的例子得出来的 <select id="province">   <option value="">----请选择- ...

  7. 2019 多点Dmalljava面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.多点Dmall等公司offer,岗位是Java后端开发,因为发展原因最终选择去了多点Dmall,入职一年时间了 ...

  8. EHLIB 安装方法

    Ehlib安装方法  路人甲 2010-05-05 23:01:37 安装文件自带的Readme.txt中的安装过程如下: 1. Delphi 5.x - 7.x, Delphi 9.X Win32, ...

  9. vue-router 在新窗口打开页面的功能

    项目中,需要点击链接后再新窗口打开页面,大家知道vue是单页面应用开发框架,那么也不是不可以实现这个功能 很简单,详情看下面 1.<router-link>标签实现新窗口打开 <ro ...

  10. Python 之configparser读取配置操作类

    一.为什么要封装 我们为什么要封装,我相信你们在项目开发过程中深有体会,那么这个读取配置工具类,又是为了什么? 为了项目参数配置的灵活性,不要改动到源码 为了信息的安全(一定层面的),体现代码重用性 ...