题目大意
参见截图
题解
之前做过一道名为电路图的神题,所以很快就发现了几个有用的结论:
- L的数量-R的数量=4.
- 一个序列满足题意当且仅当序列中不存在两个相邻的R,即所有的R都是分开的.
- 首尾的两个字符不能同时为R,因为在环上,首尾是相邻的.
利用插空法,可以得出公式:
ans=C5n2+3−C5n2+1
不妨令 t=n2 ,为了避免讨论t+1,t+3与5的大小关系,我们对式子做进一步化简:
ans=C5t+3−C5t+1=t2(t+1)(t−1)12
然后写个高精度就行了。
乘法部分,我不太会写压位,就用的 NTT.
结构体中数组开大了会崩溃,扩个栈就好了(具体原理我不清楚).
参考代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 550000
const 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;
}