Codeforces 1045 H. Self-exploration

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/86157071

纪念一下,人生中AC的第一道H题。。。。。。
虽然人家搬了题我才做的。。。。
在这里插入图片描述在这里插入图片描述题解:发现对于子任务4就是一个组合数,可以 O ( 1 ) O(1) ,剩下的数位dp就行。
在这里插入图片描述
AC Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100005
#define mod 1000000007
using namespace std;

char A[maxn],B[maxn];
int a,b,c,d,ra,rb,rc,rd;
int fac[maxn*2]={1,1},inv[maxn*2]={1,1},invf[maxn*2]={1,1};
inline int C(int a,int b)
{
	return fac[a] * 1ll * invf[b] % mod * invf[a-b] % mod;
}

int main()
{
	for(int i=2;i<maxn*2;i++)
		fac[i] = 1ll * fac[i-1] * i % mod,
		inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod,
		invf[i] = 1ll * invf[i-1] * inv[i] % mod;
	
	scanf("%s",A),scanf("%s",B);
	scanf("%d%d%d%d",&a,&b,&c,&d);
	ra=a,rb=b,rc=c,rd=d;
	
	int lena = strlen(A) , lenb = strlen(B) , ans = 0;
	
	for(int i=0;i<lena;i++) A[i] -= '0';
	for(int i=0;i<lenb;i++) B[i] -= '0';
	
	if(lenb > a+b+c+d+1)
	{
		//head is 1
		if(c == b) // tail is 1
		{
			if(c) ans = (ans + 1ll * C(d+c+1-1,c+1-1) * C(a+c-1,c-1) % mod) % mod;
			else if(a==0) 
			{
				ans ++;
			}
		}
		else if(c == b+1)// tail is 0 
		{
			ans = (ans + 1ll * C(d+c-1,c-1) * C(a+c-1,c-1) % mod) % mod;
		}
	}
	else if(lenb < a+b+c+d+1)
	{
		ans += 0;
	}
	else 
	{
		int i;
		for(i=1;i<lenb && a>=0 && b>=0 && c>=0 && d>=0;i++)
		{
			if(B[i]) // when B[i] is 1 we can add 
			{
				if(B[i-1])
					c--;
				else 
					a--;
				if(a>=0 && c>=0)
				{
				
					//head is 0
					if(c==b) // tail is 0
					{
						if(c) ans = (ans + 1ll * C(a+c+1-1,c+1-1) * C(d+c-1,c-1) % mod) % mod;
						else if(d==0) 
						{
							ans++;
						}
					}
					else if(b == c+1)//tail is 1
					{
						ans = (ans + 1ll * C(a+b-1,b-1) * C(d+b-1,b-1) % mod) % mod;
					}
				}
					
				if(B[i-1])
					c++ , d--;
				else 
					a++ , b--;				
			}
			else 
			{
				if(B[i-1])
					c--;
				else 
					a--;
			}
			
		}
		
		if(i == lenb && a == 0 && b == 0 && c == 0 && d==0) ans=(ans+1)%mod;
	}
	
	a = ra , b = rb , c = rc , d = rd;
	if(lena > a+b+c+d+1)
	{
		//head is 1
		if(c == b) // tail is 1
		{
			if(c) ans = (ans - 1ll * C(d+c+1-1,c+1-1) * C(a+c-1,c-1) % mod) % mod;
			else if(a == 0)
			{
				ans--;
			}
		}
		else if(c == b+1)// tail is 0 
		{
			ans = (ans - 1ll * C(d+c-1,c-1) * C(a+c-1,c-1) % mod) % mod;
		}
	}
	else if(lena < a+b+c+d+1)
	{
		ans -= 0;
	}
	else 
	{
		int i;
		for(i=1;i<lena && a>=0 && b>=0 && c>=0 && d>=0;i++)
		{
			if(A[i]) // when A[i] is 1 we can add 
			{
				if(A[i-1])
					c--;
				else 
					a--;
					
				if(a>=0 && c>=0)
				{
				
					//head is 0
					if(c==b) // tail is 0
					{
						if(c) ans = (ans - 1ll * C(a+c+1-1,c+1-1) * C(d+c-1,c-1) % mod) % mod;
						else if(d==0) 
						{
							ans--;
						}
					}
					else if(b == c+1)//tail is 1
					{
						ans = (ans - 1ll * C(a+b-1,b-1) * C(d+b-1,b-1) % mod) % mod;
					}
				}
					
				if(A[i-1])
					c++ , d--;
				else 
					a++ , b--;				
			}
			else 
			{
				if(A[i-1])
					c--;
				else 
					a--;
			}
		}
		
		/*
		if(i == lena && a == 0 && b == 0 && c == 0 && d==0) 
			ans=(ans-1)%mod;
		*/
	}
	
	
	printf("%d\n",(ans+mod)%mod);
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/86157071