[CSP-S模拟测试]:visit(组合数学+exLucas+CRT)
题目传送门(内部题6)
输入格式
第一行包含两个整数$T$,$MOD$;
第二行包含两个整数$n$,$m$,表示$dirty$房子的位置。
输出格式
一行一个整数,表示对$MOD$取模之后的答案。
样例
样例输入:
4 10
2 2
样例输出:
6
数据范围与提示
对于$30\%$的数据,$T \leqslant 100$;
对于另外$30\%$的数据,$MOD$为质数;
对于全部数据,$1 \leqslant T \leqslant 100,000;-T \leqslant n,m \leqslant T;1 \leqslant MOD \leqslant {10}^9+7$,MOD为若干互不相同的质数的乘积。
题解
$30\%$算法:
考虑$DP$,定义$dp[i][j][k]$表示在时间为$i$的时候走到了$(j,k)$,$pure$只能从上下左右四个方向走过来,那么很容易就能写出$dp$式子:
$dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j+1][k]+dp[i-1][j][k-1]+dp[i-1][j][k+1]$。
但是这并不能轻松的拿到$30$分,需要注意的是,$n$和$m$有可能是负数,但是我们有发现,根据出租车几何,不管$(n,m)$这个点在第几象限,显然我们都能把它当成在第一象限来解决,用$abs$函数吧$n$和$m$都转化为正数即可。
而且$DP$的边界要搞清,因为$pure$最多会往上下左右四个方向走$T$步,所以$dp$的边界要设成$-T\sim T$。
当然$dp$式子中也要$[j][k]$两维也要$+100$来处理负数的情况。
总之,$30\%$的算法也不好打。
时间复杂度:$O(n^3)$。
期望得分:$30$分。
实际得分:$30$分。
$60\%$算法:
对于如此之大的数据范围,显然我们不能在用哪怕一个二维数组来存了。
那么我们来考虑转化这个问题,因为我们最终肯定要向右走$n$步,向上走$m$步,然后剩下的$T-n-m$步用来浪费到向右走再走回来和向上走再走回来。
所以可以发现:$T=n+m+2(x+y)$(式中x表示向右走的多余步数,y表示向上走的多余步数)。
我们还可以发现,如果$n+m<T$或者是$(T-n-m)\mod2\neq0$时都无解。
而且,如果我们确定了$x$和$y$的其中一个,我们就能确定另一个。
在来考虑这样一个问题:
如果有$n$个物品,每个物品有$a_n$个,那么本质不同的排列数即为:
$\frac{k!}{a_1\times a_2\times...\times a_{n-1}\times a_n}$
那么这道题的答案即为:
$\frac{T!}{x!\times y!\times (n+x)!\times (m+y)!}$
然后因为$mod$是一个质数,所以我们可以直接用$Lucas$定理和阶乘逆元轻松解决。
时间复杂度:$O(n\log n)$。
空间复杂度:$T$。
期望得分:$60$分。
$100\%$算法:
我们发现$mod$并不是一个质数,但是$mod$是若干个互不相同质数的乘积,于是想到了中国剩余定理($CRT$),先将$mod$分解,然后计算对于没一个分解出来的模数计算出来的结果,$Lucas$定理即可轻松解决,最后再用$CRT$合并即可。
代码时刻
$30\%$算法:
- #include<bits/stdc++.h>
- using namespace std;
- int t,n,m,mod;
- long long dp[101][202][202];
- int main()
- {
- scanf("%d%d%d%d",&t,&mod,&n,&m);
- n=abs(n);
- m=abs(m);//变为正数
- dp[0][100][100]=1;
- for(int i=1;i<=t;i++)
- for(int j=-t;j<=t;j++)
- for(int k=-t;k<=t;k++)
- dp[i][j+100][k+100]=(
- dp[i][j+100][k+100]+
- dp[i-1][j+1+100][k+100]+
- dp[i-1][j+100][k+1+100]+
- dp[i-1][j-1+100][k+100]+
- dp[i-1][j+100][k-1+100])%mod;//状态转移
- printf("%lld",dp[t][n+100][m+100]);
- return 0;
- }
$100\%$算法
- #include<bits/stdc++.h>
- using namespace std;
- int t,mod,n,m;
- int wzc[500];
- long long fac[200000],rec[500];
- long long ans;
- long long qpow(long long x,long long y,long long p)
- {
- long long res=1;
- while(y)
- {
- if(y%2)res=(res*x)%p;
- y>>=1;
- x=(x*x)%p;
- }
- return res;
- }
- long long get_C(long long x,long long y,long long p)
- {
- if(x<y)return 0;
- return fac[x]%p*qpow(fac[x-y]*fac[y]%p,p-2,p)%p;
- }
- long long lucas(long long x,long long y,long long p)//Lucas定理
- {
- if(!y)return 1;
- return (get_C(x%p,y%p,p)*lucas(x/p,y/p,p))%p;
- }
- void pre_mod(int x)//分解模数
- {
- for(int i=2;i<=sqrt(mod);i++)
- if(!(x%i))
- {
- wzc[++wzc[0]]=i;
- x/=i;
- }
- if(x>1)wzc[++wzc[0]]=x;
- }
- void pre_work(int x)
- {
- int maxn=min(x-1,t);
- fac[0]=1;
- for(int i=1;i<=maxn;i++)
- fac[i]=fac[i-1]*i%x;//预处理阶乘
- }
- int main()
- {
- scanf("%d%d%d%d",&t,&mod,&n,&m);
- n=abs(n);
- m=abs(m);
- pre_mod(mod);
- for(int i=1;i<=wzc[0];i++)
- {
- pre_work(wzc[i]);
- for(int j=n;j<=t-m;j+=2)
- rec[i]=(rec[i]+lucas(t,j,wzc[i])*lucas(j,(j-n)/2,wzc[i])%mod*lucas(t-j,(t-j-m)/2,wzc[i])%mod)%mod;
- }
- for(int i=1;i<=wzc[0];i++)
- ans=(ans+mod/wzc[i]*rec[i]%mod*qpow(mod/wzc[i],wzc[i]-2,wzc[i])%mod)%mod;//CRT
- printf("%lld",ans);
- return 0;
- }
rp++
[CSP-S模拟测试]:visit(组合数学+exLucas+CRT)的更多相关文章
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- Android单元测试与模拟测试详解
测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabri ...
- [开源]微信在线信息模拟测试工具(基于Senparc.Weixin.MP开发)
目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具 ...
- 安装nginx python uwsgi环境 以及模拟测试
uwsgi帮助文档: http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html http://uwsgi-docs.re ...
- 利用Python中的mock库对Python代码进行模拟测试
这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下 ...
- 转 C#实现PID控制的模拟测试和曲线绘图
C#实现PID控制的模拟测试和曲线绘图 本文分两部分,一部分是讲PID算法的实现,另一部分是讲如何用动态的曲线绘制出PID运算的结果. 首先,PID算法的理论模型请参考自动控制理论,最早出现的是模 ...
- Mockito:一个强大的用于Java开发的模拟测试框架
https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...
- NOIP模拟测试1(2017081501)
好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...
- Mock 模拟测试简介及 Mockito 使用入门
Mock 是什么mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是mock对象.mock对象就是真实对象在调试期间的代 ...
随机推荐
- SwipeRefreshLayout和RecyclerView类
1 SwipeRefreshLayout和RecyclerView之间的关系 内容栏上下滚动是RecyclerView控制的,只有当内容栏滑动到最顶上时,再也拉不动了的时候,这个时候将动作交给Swip ...
- [转帖]IDC发布2018下半年中国公有云市场报告
IDC发布2018下半年中国公有云市场报告:AWS以6.4%的份额名列第四 http://www.itpub.net/2019/05/06/1793/ 电信的公有云 好像是用的 华为的技术. AWS在 ...
- HDU 1864 最大报销额 0-1背包
HDU 1864 最大报销额 0-1背包 题意 现有一笔经费可以报销一定额度的发票.允许报销的发票类型包括买图书(A类).文具(B类).差旅(C类),要求每张发票的总额不得超过1000元,每张发票上, ...
- 【LGR-063】洛谷11月月赛 I & MtOI2019 Ex Div.2
[MtOI2019]黑蚊子多: 送分向水题,直接模拟即可. #include<iostream> #include<cstdio> #define N 1505 using n ...
- Python作图包含type3字体解决方案
1. 解决方案 matplotlib.rcParams[‘text.usetex’] = True
- 剑指offer-二叉搜索树的第k个结点树-python
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...
- vue 模拟去哪网
模拟项目中遇到的问题,总结如下: 1.争对轮播图 使用vue-awesome-swiper npm install vue-awesome-swiper@2.6.7 --save //因为此版本稳定 ...
- Tomcat编译jsp生成Servlet文件的存放位置
转自:http://www.cnblogs.com/Leon5/archive/2010/12/07/1899300.html Tomcat将jsp编译成servlet后的文件存放在\work\Cat ...
- python 调用dll 动态链接库 结构体参数及回调函数等示例
结构体示例: 这里是 C 代码的部分,主要是结构体的声明和回调函数定义. // 新版本定义 typedef enum { DevCard, DevLocator, DevReader } DevTyp ...
- MySQL索引优化与分析(重要)
建表SQL CREATE TABLE staffs ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR (24) NULL DEFAULT '' COM ...