BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp
其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:
$A[i]\equiv B[i](mod$ $P[i])$.
对于这个东西,你可以这么思考:
如果最后能求出一个解,那么这个解的增量一定是 $lcm(P[1],P[2].....).$
所以,只要你能找到一坨 $P[i]$,使得它们的 $lcm$ 等于你想要的东西,你就可以用 $excrt$来解.
p话扯完了,我们步入正题:
假设没有障碍,有 $n$ 行 $m$ 列,那么答案即为 $C_{n+m}^{n}.$
这个东西就代表你一共会走 $n+m$ 步,其中 $n$ 步的方向是向上的.
而如果有障碍,我们考虑按照每一个障碍点一次枚举.
首先,将障碍按照横纵坐标从小到大拍一个序,那么考虑我们枚举到第 $i$ 个障碍.
令 $f[i]$ 表示从起点到第 $i$ 个障碍所走过的合法的方案数,$(x,y)$ 表示横纵坐标.
总方案为 $C_{x+y}^{y},$ 不合法的方案为 $\sum f[前面障碍]$.
如果随便减的话,我们可能减多,所以我们考虑按照策略去减.
我们想让每一次减掉的都互不相同,所以我们考虑枚举第一个不合法的障碍.
即 $C_{x+y}^{y}-\sum_{j=1}^{i-1}f[j]\times calc(j到i的方案数).$
这样,我们等于说是强制性的每次只减掉第一个障碍碰到 $j$ 的方案数,不会减多.
这个题的模数不是素数,所以需要将模数分解成若干个素数,然后依次取模,最后在用 $excrt$ 合并.
Code:
- #include <cstdio>
- #include <algorithm>
- #define N 1000006
- #define ll long long
- #define setIO(s) freopen(s".in","r",stdin)
- using namespace std;
- ll F[N];
- int array[10]={0,3,5,6793,10007};
- struct Node {
- ll x,y;
- Node(ll x=0,ll y=0):x(x),y(y){}
- }arr[N];
- bool cmp(Node a,Node b) {
- return a.x==b.x?a.y<b.y:a.x<b.x;
- }
- ll qpow(ll base,ll k,ll mod) {
- ll tmp=1;
- for(;k;k>>=1,base=base*base%mod)
- if(k&1) tmp=tmp*base%mod;
- return tmp;
- }
- struct Lucas {
- int mod;
- int fac[N];
- int inv(int i) {
- return (int)qpow(i,mod-2,mod);
- }
- void init(int p) {
- mod=p,fac[0]=1;
- for(int i=1;i<=mod;++i) fac[i]=(ll)fac[i-1]*i%mod;
- }
- int C(int x,int y) {
- if(y>x) return 0;
- if(y==0) return 1;
- return (int)(1ll*fac[x]*inv(fac[y])%mod*inv(fac[x-y])%mod);
- }
- int solve(ll x,ll y) {
- if(y>x) return 0;
- if(y==0) return 1;
- return (int)(1ll*solve(x/mod,y/mod)*C(x%mod,y%mod)%mod);
- }
- }comb[8];
- struct excrt {
- ll arr[N],brr[N];
- ll exgcd(ll a,ll b,ll &x,ll &y) {
- if(!b) {
- x=1,y=0;
- return a;
- }
- ll gcd=exgcd(b,a%b,x,y),tmp=x;
- x=y,y=tmp-a/b*y;
- return gcd;
- }
- ll Excrt() {
- int i,j;
- ll ans=arr[1],M=brr[1];
- for(i=2;i<=4;++i) {
- ll a=M,b=brr[i],c=arr[i]-ans,gcd,x,y;
- gcd=exgcd(a,b,x,y),b=abs(b/gcd);
- x=(x*(c/gcd)%b+b)%b;
- ans+=M*x;
- M*=brr[i]/__gcd(brr[i],M);
- ans=(ans%M+M)%M;
- }
- return ans;
- }
- }crt;
- ll C(ll a,ll b,int ty) {
- if(ty==0)
- return comb[0].solve(a,b);
- else {
- int i,j;
- for(i=1;i<=4;++i) {
- crt.arr[i]=comb[i].solve(a,b);
- crt.brr[i]=array[i];
- }
- }
- return crt.Excrt();
- }
- int main() {
- int i,j,k,flag;
- // setIO("input");
- ll n,m,mod;
- scanf("%lld%lld%d%lld",&n,&m,&k,&mod),flag=(mod==1019663265);
- if(!flag) {
- comb[0].init(mod);
- }
- else {
- for(i=1;i<=4;++i)
- comb[i].init(array[i]);
- }
- for(i=1;i<=k;++i)
- scanf("%lld%lld",&arr[i].x,&arr[i].y);
- arr[++k].x=n,arr[k].y=m;
- sort(arr+1,arr+1+k,cmp);
- for(i=1;i<=k;++i) {
- F[i]=C(arr[i].x+arr[i].y,arr[i].y,flag);
- for(j=1;j<i;++j) {
- if(arr[j].y<=arr[i].y)
- F[i]=(F[i]-(F[j]*C(arr[i].x-arr[j].x+arr[i].y-arr[j].y,arr[i].y-arr[j].y,flag)%mod)+mod)%mod;
- }
- }
- printf("%lld\n",F[k]);
- return 0;
- }
BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp的更多相关文章
- bzoj 3782 上学路线 卢卡斯定理 容斥 中国剩余定理 dp
LINK:上学路线 从(0,0)走到(n,m)每次只能向上或者向右走 有K个点不能走求方案数,对P取模. \(1\leq N,M\leq 10^10 0\leq T\leq 200\) p=10000 ...
- BZOJ 3782: 上学路线 [Lucas定理 DP]
3782: 上学路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 192 Solved: 75[Submit][Status][Discuss] ...
- bzoj3782上学路线(Lucas+CRT+容斥DP+组合计数)
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3782 有部分分的传送门:https://www.luogu.org/problemnew/ ...
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- $bzoj2560$ 串珠子 容斥+$dp$
正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- BZOJ.4767.两双手(组合 容斥 DP)
题目链接 \(Description\) 棋盘上\((0,0)\)处有一个棋子.棋子只有两种走法,分别对应向量\((A_x,A_y),(B_x,B_y)\).同时棋盘上有\(n\)个障碍点\((x_i ...
- BZOJ 2005 [Noi2010]能量采集 (数学+容斥 或 莫比乌斯反演)
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 4493 Solved: 2695[Submit][Statu ...
随机推荐
- markdown中使用缩进
在markdown中直接敲空格是不生效的. 使用html标签来实现 一个空格大小的表示: 两个空格的大小表示: 不换行空格: 别忘记分号 参考了大神的文章: markdown空格缩进以及HTML ...
- 并不对劲的复健训练-p5212 SubString
题目大意 有一个串\(s\),一开始只知道它的一个前缀.有\(q\)(\(q\leq 10^4\))个操作,操作有两种:1.给一个字符串,表示\(s\)(\(s\)总长\(\leq 6\times 1 ...
- EasyUI_前台js_分页
1.html: <table id="DataTb" title="客户信息" class="easyui-datagrid" sty ...
- 使用EF Core 连接远程oracle 不需要安装oracle客户端方法
连接字符串: Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=IP地址(PORT=1521))(CONNECT_DATA=(SERVICE_ ...
- luogu题解P2502[HAOI2006]旅行--最小生成树变式
题目链接 https://www.luogu.org/problemnew/show/P2502 分析 一个很\(naive\)的做法是从\(s\)到\(t\)双向BFS这当然会TLE 这时我就有个想 ...
- 始终让footer在底部
1.footer保持在页面底部 需求: 我们希望footer能在窗口最底端,但是由于页面内容太少,无法将内容区域撑开,从而在 footer 下面会留下一大块空白 第一种方法:采用 flexbox布局模 ...
- sql server 2012使用新特性offset和fetch next完成分页操作
1 select * from HumanResources.Department order by DepartmentID offset rows fetch next rows only; of ...
- 第二十四篇 jQuery 学习6 删除元素
jQuery 学习6 删除元素 上节课我们做了添加元素,模拟的是楼主发的文章,路人评论,那么同学们这节课学了删除之后,去之前的代码上添加一个删除,模拟一个楼主删除路人的评论. jQuery的删除方 ...
- JavaMaven【六、生命周期】
Maven有三个独立的生命周期,每个生命周期都不会出发别的生命周期的操作 若直接执行生命周期后面的操作,maven会默认执行前面的操作 如项目创建好后,直接执行mvn install,会默认依次执行c ...
- JavaJDBC【四、存储过程的使用】
Mysql还没学到存储过程,不过语法比较简单 此处不深究数据库中的存储过程怎么创建,后面在mysql的学习笔记里再做整理 今天只整理java中如何调用存储过程 语句 CallableStatement ...