CF 1045 H. 자기 탐사 문제 해결 보고서

CF 1045 H. 자기 탐사

계정에 문자열의 구조를 복용해야

1...0....1....0.....1...

반면 이와 같이, \ (01 \)\ (10 \)의 표시를 교대 전환점

첫 번째 문자열 길이는되어야 \ (A + B + C + D + 1 \) (대표 \ (00,01,10,11 \) 번호)와 제해야 (1 \)를 \ 도 충족시켜야 \ (B = C를 \의 B = C-LOR. 1 \) , 파형 계수가 고려되어 있지 한정

우리는 사실, 우리 모두가 둘 필요가 있음을 발견 \ (0 \)를 , 전환점으로 번호를 선택한 다음 \ (1 \) 할 수는 나머지 그것으로 직접 전환에 따라 채우기 위해

주목 \ (\ 0)(1 \) \ 수가있다 \을 (A + C \)\ (B + D + 1 \ )

이어서 처음에 전환점 회만 발생해야하고, 그래서 프로그램의 수이다 \ (\하기 Binom {A + C -1} {C} \) 와 (\하기 Binom {B + D} {B} \) \ , 승산 원리 거기에

그리고 우리는 가장 높은 비트 스터핑에서 시작, 한계를 고려

현재 비트 인 경우 \ (0 \) 만 채울 수 있습니다 \ (0 \)를 다시 채우기 위해 계속

인 현재 인 경우 \ (1 \) , 입력 \ (0 \) 는 거의 한계에 의해 믿을 수있는, 쉽게 채울 수 뒷면 후,하지만 최고 수준의 제국은입니다 \ (0 \) , 입력 \ (1 \)를 에 또한 채우기 위해 앞으로 계속

참고 조금 참고 경계 판사를 작성하는 과정의 배열 범위가 무엇인지, 그렇지 않으면 수도


암호:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#include <algorithm>
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
//#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
#define gc() getchar()
template <class T>
void read(T &x)
{
    int f=0;x=0;char c=gc();
    while(!isdigit(c)) f|=c=='-',c=gc();
    while(isdigit(c)) x=x*10+c-'0',c=gc();
    if(f) x=-x;
}
const int N=2e5+1;
const int mod=1e9+7;
char s[N],t[N];
int fac[N],inv[N];
inline void add(int &x,int y){x+=y;if(x>=mod) x-=mod;}
#define mul(a,b) (1ll*(a)*(b)%mod)
inline int qp(int d,int k)
{
    int f=1;
    while(k)
    {
        if(k&1) f=mul(f,d);
        d=mul(d,d);
        k>>=1;
    }
    return f;
}
int C(int m,int n)
{
    if(m==n) return 1;
    return mul(fac[m],mul(inv[m-n],inv[n]));
}
int cal(int c00,int c01,int c10,int c11,char *s)
{
    int n=strlen(s+1),l=c00+c01+c10+c11;
    if(c10!=c01&&c10!=c01+1) return 0;
    if(n>l+1) return mul(C(c00+c10-1,c10-1),C(c11+c01,c01));
    if(n<l+1) return 0;
    int pre=1,ret=0;
    for(int i=2;i<=n;i++)
    {
        if(s[i]=='0')
        {
            if(pre) --c10;
            else --c00;
            pre=0;
        }
        else
        {
            if(pre) --c10;
            else --c00;
            if(c01!=c10||c01!=c10+1) add(ret,mul(C(c00+c10,c10),C(c11+c01-1,c01-1)));
            if(pre) ++c10;
            else ++c00;

            if(pre) --c11;
            else --c01;
            pre=1;
        }
        if(c00<0||c01<0||c10<0||c11<0) break;
    }
    return ret;
}
int ck(int c00,int c01,int c10,int c11,char *s)
{
    int n=strlen(s+1),l=c00+c01+c10+c11;
    if(n!=l+1) return 0;
    int pre=s[1]-'0';
    for(int i=2;i<=n;i++)
    {
        if(pre)
        {
            if(s[i]=='1') --c11;
            else --c10;
        }
        else
        {
            if(s[i]=='1') --c01;
            else --c00;
        }
        pre=s[i]-'0';
    }
    return !c00&&!c01&&!c10&&!c11;
}
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    scanf("%s%s",s+1,t+1);
    fac[0]=1;
    for(int i=1;i<N;i++) fac[i]=mul(fac[i-1],i);
    inv[N-1]=qp(fac[N-1],mod-2);
    for(int i=N-2;~i;i--) inv[i]=mul(inv[i+1],i+1);
    int c00,c01,c10,c11;
    read(c00),read(c01),read(c10),read(c11);
    int ans=((cal(c00,c01,c10,c11,t)-cal(c00,c01,c10,c11,s)+ck(c00,c01,c10,c11,t))%mod+mod)%mod;
    printf("%d\n",ans);
    return 0;
}

2019년 6월 2일

추천

출처www.cnblogs.com/butterflydew/p/10962071.html