中国剩余定理——zoj 3538

排列组合的公式推出来比较简单
剩下(x/y)%MOD=z 求z比较麻烦
先temp=x%MOD
再循环i=0->N
直到: (temp+i*MOD)%y==0
    z=(temp+i*MOD)/y
View Code
#include<stdio.h>
#include
<iostream>
#include
<algorithm>
using namespace std;

const long long MOD=1000000007;

struct data
{
int no;
char s;
}node[
109];

long long Mon(long long n,long long p,long long m)
{
n
=n%m;
long long all=1;
while(p>0)
{
if((p&1)==1)
all
=all*n%m;
n
=(n*n)%m;
p
>>=1;
}

return all;
}

int cmp(data a,data b)
{
return a.no<b.no;
}

int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,k;
for(i=0;i<m;i++)
{
cin
>>node[i].no>>node[i].s;
//scanf("%d %c",&node[i].no,&node[i].s);
}


long long sum=1;
if(m==0)
{
sum
=Mon(3,n-1,MOD);
sum
=(sum*4)%MOD;
printf(
"%lld\n",sum);
continue;
}

sort(
&node[0],&node[m],cmp);
int ok=0;
for(i=1;i<m;i++)
{
if(node[i-1].s==node[i].s&&(node[i-1].no+1)==node[i].no)
{
printf(
"0\n");
ok
=1;
break;
}
}
if(ok==1)continue;

if((node[0].no-1)==0)sum=1;
else
sum
=Mon(3,node[0].no-1,MOD);

/////////////////
//printf("%lld\n",sum);

long long tsum=1;
for(i=1;i<m;i++)
{

int t=node[i].no-node[i-1].no-1;
if(node[i-1].s==node[i].s)
{
if((t%2)==0)
{
tsum
=(Mon(3,t,MOD)+(-1+MOD))%MOD;
tsum
=(tsum*3)%MOD;
for(k=0;;k++)
{
if((tsum+k*MOD)%4==0)
break;
}

tsum
=((tsum+k*MOD)/4)%MOD;
}
else
{
tsum
=(Mon(3,t,MOD)+1)%MOD;

tsum
=(tsum*3)%MOD;
for(k=0;;k++)
{
if(((tsum+k*MOD))%4==0)
break;
}

tsum
=((tsum+k*MOD)/4)%MOD;
}
}
else
{
if((t%2)==0)
{
tsum
=Mon(3,t+1,MOD)+1;
tsum
=tsum%MOD;
for(k=0;;k++)
{
if((tsum+MOD*k)%4==0)
break;
}

tsum
=((tsum+k*MOD)/4)%MOD;
}
else
{
tsum
=Mon(3,t+1,MOD)+(-1+MOD);
tsum
=tsum%MOD;
for(k=0;;k++)
{
if((tsum+MOD*k)%4==0)
break;
}

tsum
=((tsum+k*MOD)/4)%MOD;
}
}
/////////////
//printf("%lld\n",tsum);
sum=(sum*tsum)%MOD;
}

if((n-node[m-1].no)==0)tsum=1;
else
tsum
=Mon(3,n-node[m-1].no,MOD);
/////////////////
//printf("%lld\n",tsum);

sum
=(sum*tsum)%MOD;
printf(
"%lld\n",sum);
}
}
原文地址:https://www.cnblogs.com/huhuuu/p/2181711.html