zoukankan      html  css  js  c++  java
  • 【模板】带有直线限制的NE Latice Path计数

    Pro:
    ((0,0))出发走到((n,m))
    给定(y=x+l)(y=x+r)两条直线
    要求不能穿过(可以接触)这两条直线
    求方案数
    (n,m,l,r<=1e6)
    Sol:
    参考了这篇blog
    https://www.cnblogs.com/xzyxzy/p/9812585.html
    注意预处理的范围要为原数据范围的10倍

    #include<bits/stdc++.h>
    #define N 11000000
    #define db double
    #define ll long long
    #define ldb long double
    #define ull unsigned long long
    using namespace std;
    const int h=3,ki=149,mo=1e9+7;
    int mod(int x){return (x%mo+mo)%mo;}
    int inc(int x,int k){x+=k;return x<mo?x:x-mo;}
    int dec(int x,int k){x-=k;return x>=0?x:x+mo;}
    int ksm(int x,int k)
    {
    	int ans=1;
    	while(k){if(k&1)ans=1ll*ans*x%mo;k>>=1;x=1ll*x*x%mo;}
    	return ans;
    }
    int inv(int x){return ksm(mod(x),mo-2);}
    int read()
    {
    	char ch=0;int x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
    	return x*flag;
    }
    void write(int x)
    {
    	if(!x)return (void)putchar(48);
    	if(x<0)putchar(45),x=-x;
    	int len=0,p[20];
    	while(x)p[++len]=x%10,x/=10;
    	for(int i=len;i>=1;i--)putchar(p[i]+48);
    }
    const db eps=1e-7,inf=1e9+7,pi=acos(-1);
    db Read(){db x;scanf("%lf",&x);return x;}
    void Write(db x){printf("%lf",x);}
    int fac[N],vac[N];
    void prepare(int n)
    {
    	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mo;
    	vac[n]=inv(fac[n]);for(int i=n;i>=1;i--)vac[i-1]=1ll*vac[i]*i%mo; 
    }
    int C(int n,int m){return n>=m?1ll*fac[n]*vac[m]%mo*vac[n-m]%mo:0;}
    void fold(int &x,int &y,int k){swap(x,y);x-=k;y+=k;}
    int solve(int n,int m){return (n>=0&&m>=0)?C(n+m,n):0;}
    int work(int n,int m,int l,int r)
    {
    	l--;r++;
    	int x,y,ans=solve(n,m);
    	
    	x=n;y=m;
    	while(true)
    	{
    		fold(x,y,l);if(x<0||y<0)break;ans=dec(ans,solve(x,y));
    		fold(x,y,r);if(x<0||y<0)break;ans=inc(ans,solve(x,y));
    	}
    	
    	x=n;y=m;
    	while(true)
    	{
    		fold(x,y,r);if(x<0||y<0)break;ans=dec(ans,solve(x,y));
    		fold(x,y,l);if(x<0||y<0)break;ans=inc(ans,solve(x,y));
    	}
    	return ans;
    }
    int main()
    {
    	prepare(1e7);
    	int n=read(),m=read(),l=read(),r=read();
        write(work(n,m,-l,+r));
        return 0;
    }
    
  • 相关阅读:
    【pandas实战】时间差计算
    【pandas实战】数据分类整理
    海量数据处理方法整理记录
    Springboot中实现策略模式+工厂模式
    实现一个秒杀系统
    Redis实现的分布式锁和分布式限流
    实现分布式服务注册及简易的netty聊天
    聊聊数据库乐观锁和悲观锁,乐观锁失败后重试
    聊聊RPC原理二
    聊聊kafka结构
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10292933.html
Copyright © 2011-2022 走看看