zoukankan      html  css  js  c++  java
  • 小米网络赛 热身赛 A题 ABBA

    Pro:
    https://ac.nowcoder.com/acm/contest/8409/A
    计算满足可以划分为(n)(AB)(m)(BA)的长度为(2*(n+m))的AB序列个数
    (n,m<=1e6)

    Sol:
    考虑怎么判断一个序列是否合法
    可以从左到右依次处理
    记录当前有x个A,y个B
    (x<=n)(y<=m)时显然是合法的
    因为从贪心的角度想
    (n)(A)和前(m)(B)一定要分别用来构成(AB)(BA)
    (x>n)时,则每一个a都需要用来组成(BA)
    这时就要求每一个A都能找到一个B
    写成不等式的形式就是(x-n<=y)
    同理可得(y-m<=x)

    简单处理这两个人不等式后可得(-n<=y-x<=m)
    这个问题就转为了带有两条直线限制的NE Latice Path问题
    可以DP,也可以直接算
    直接算的话就是这个题:https://www.luogu.com.cn/problem/P3266
    直接上板子就可以了
    板子链接:https://www.cnblogs.com/Creed-qwq/p/10292933.html

    #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,m;
    	while(~scanf("%d%d",&n,&m))write(work(n+m,n+m,-n,+m)),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 1291 Round #616 (Div. 2) B
    总结
    刷新DNS解析缓存+追踪+域名解析命令
    数学--数论--Hdu 5793 A Boring Question (打表+逆元)
    Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析
    LeetCode 117 Populating Next Right Pointers in Each Node II
    LeetCode 116 Populating Next Right Pointers in Each Node
    test test
    LeetCode 115 Distinct Subsequences
    LeetCode 114. Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/13961365.html
Copyright © 2011-2022 走看看