bzoj4201 多边形序列

来源:互联网 发布:字体管家软件pc 编辑:程序博客网 时间:2024/06/06 05:53

题目大意

参见截图
题面截图

题解

之前做过一道名为电路图的神题,所以很快就发现了几个有用的结论:

  • L的数量-R的数量=4.
  • 一个序列满足题意当且仅当序列中不存在两个相邻的R,即所有的R都是分开的.
  • 首尾的两个字符不能同时为R,因为在环上,首尾是相邻的.

利用插空法,可以得出公式:

ans=C5n2+3C5n2+1

不妨令t=n2,为了避免讨论t+1,t+3与5的大小关系,我们对式子做进一步化简:
ans=C5t+3C5t+1=t2(t+1)(t1)12

然后写个高精度就行了。
乘法部分,我不太会写压位,就用的NTT.
结构体中数组开大了会崩溃,扩个栈就好了(具体原理我不清楚).

参考代码

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 550000const int G=998244353,g=3;int exp(int a,int k){    int an=1;    for(;k;k>>=1)    {        if(k&1)        {            an=1ll*an*a%G;        }        a=1ll*a*a%G;    }    return an;}int A[MAXN<<1],B[MAXN<<1],N,W[MAXN<<1];void NTT(int X[],int nn,int ty){    int i,j,k,m,t1,t2;    for(i=0;i<nn;i++)    {        for(j=0,k=i,m=1;m<nn;m<<=1,j=(j<<1)|(k&1),k>>=1);        if(i<j)        {            t1=X[i];            X[i]=X[j];            X[j]=t1;        }    }    W[0]=1;    for(m=1;m<nn;m<<=1)    {        t1=exp(g,G-1+ty*(G-1)/(m<<1));        for(i=1;i<m;i++)        {            W[i]=1ll*W[i-1]*t1%G;        }        for(k=0;k<nn;k+=m<<1)        {            for(i=k;i<k+m;i++)            {                t1=X[i];                t2=1ll*X[i+m]*W[i-k]%G;                X[i]=t1+t2;                X[i]-=X[i]>=G?G:0;                X[i+m]=t1-t2;                X[i+m]+=X[i+m]<0?G:0;            }        }    }    if(ty==1)    {        return ;    }    t1=exp(nn,G-2);    for(i=0;i<nn;i++)    {        X[i]=1ll*X[i]*t1%G;    }    return ;}struct big{    int x[MAXN],len;    big()    {        memset(x,0,sizeof(x));         len=0;    }    big operator = (char* s)    {        len=strlen(s);        for(int i=1;i<=len;i++)        {            x[i]=s[len-i]-'0';        }        return *this;    }    big operator = (int num)    {        char s[MAXN];        sprintf(s,"%d",num);        return *this=s;    }    big operator + (big& b)    {        big c=big();        c.len=max(len,b.len);        for(int i=1;i<=c.len;i++)        {            c.x[i]+=x[i]+b.x[i];            if(c.x[i]>9)            {                c.x[i+1]++;                c.x[i]-=10;            }        }        for(;c.x[c.len+1];c.len++);        return c;    }    big operator - (big& b)    {        big c=big();        c.len=len;        for(int i=1;i<=c.len;i++)        {            c.x[i]+=x[i]-b.x[i];            if(c.x[i]<0)            {                c.x[i+1]--;                c.x[i]+=10;            }        }        for(;c.len>1&&!c.x[c.len];c.len--);        return c;    }    big operator / (int num)    {        big c=big();        int p=0,q=0;        c.len=len;        for(int i=c.len;i>=1;i--)        {            p=10*q+x[i];            c.x[i]=p/num;            q=p%num;        }        for(;c.len>1&&!c.x[c.len];c.len--);        return c;    }    void print()    {        for(int i=len;i>=1;i--)        {            putchar('0'+x[i]);        }        return ;    }    bool mod_2()    {        return x[1]&1;    }    big operator * (big& b)    {        memset(A,0,sizeof(A));        memset(B,0,sizeof(B));        big c=big();        c.len=len+b.len;        for(N=1;N<=c.len;N<<=1);        for(int i=1;i<=len;i++)        {            A[i-1]=x[i];        }        for(int i=1;i<=b.len;i++)        {            B[i-1]=b.x[i];        }        NTT(A,N,1);        NTT(B,N,1);        for(int i=0;i<N;i++)        {            A[i]=1ll*A[i]*B[i]%G;        }        NTT(A,N,-1);        for(int i=0;i<N;i++)        {            c.x[i+1]=A[i]%10;            A[i+1]+=A[i]/10;        }        for(;c.len>1&&!c.x[c.len];--c.len);        return c;    }};char s[MAXN];int main_main(){    freopen("A.out","w",stdout);    big x=big(),a=big(),b=big(),c=big();    c=1;    scanf("%s",s);    x=s;    if(x.mod_2())    {        printf("0");        return 0;    }    x=x/2;    a=x+c;    b=x-c;    x=x*x;    x=x*a;    x=x*b;    x=x/12;    x.print();    return 0;}const int main_stack=16; char my_stack[128<<20]; int main() {   __asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");   __asm__("movl %%eax, %%esp;\n"::"a"(my_stack+sizeof(my_stack)-main_stack):"%esp");   main_main();   __asm__("movl (%%eax), %%esp;\n"::"a"(my_stack):"%esp");   return 0; }
原创粉丝点击