题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6030
题目要求给出一个长度为n的串,要求这个串中任意长度为素数的连续序列中r的数量多于或者等于b,我们不难得出只要长度为2或者3的序列都满足这个条件就能得出整个序列满足题目要求的条件,简单的证明如下:如果是长度为偶数的素数,那一定只有2,满足最小性条件,如果是大小为奇数的素数代表的连续区间,则这个奇数可以分解成若干个2和3,的短序列,由于序列条件的可加性。所以整个序列也是满足条件的。对于递推关系,可以考虑局部的转移规则,因为长度为2和3的区间需要考虑,所以我们每次递推的时候就考虑2->3长度的转移过程。用an表示末两位为rr的方案数,bn表示末位为rb的方案数,cn表示末位为br的方案数,所以总共的方案数有an+bn+cn,初值为a2=b2=c2=1,有关系 an=an-1+cn-1,bn=an-1,cn=bn-1.根据关系构造矩阵即可在O(logn)时间内求出an+bn+cn;
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define mp(a,b) make_pair((a),(b)) 17 #define P pair<int,int> 18 #define dbg(args) cout<<#args<<":"<<args<<endl; 19 #define inf 0x7ffffff 20 inline int read(){ 21 int ans=0,w=1; 22 char ch=getchar(); 23 while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} 24 while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 25 return ans*w; 26 } 27 int t; 28 ll n; 29 const int maxn=3; 30 const ll mod=1e9+7; 31 struct mat{ 32 ll a[maxn][maxn]; 33 mat() 34 { 35 f(i,0,maxn-1) 36 f(j,0,maxn-1) 37 a[i][j]=0; 38 } 39 mat operator * (const mat &x)const 40 { 41 mat c; 42 f(i,0,maxn-1) 43 f(j,0,maxn-1) 44 f(k,0,maxn-1) 45 { 46 c.a[i][j]=(c.a[i][j]+a[i][k]*x.a[k][j])%mod; 47 } 48 return c; 49 } 50 }; 51 mat pow_mod(mat A,ll k) 52 { 53 mat ans; 54 ans.a[0][0]=ans.a[1][1]=ans.a[2][2]=1; 55 while(k) 56 { 57 if(k&1)ans=ans*A; 58 A=A*A; 59 k>>=1; 60 } 61 return ans; 62 } 63 int main() 64 { 65 //freopen("input.txt","r",stdin); 66 //freopen("output.txt","w",stdout); 67 std::ios::sync_with_stdio(false); 68 t=read(); 69 mat A; 70 A.a[0][0]=A.a[0][2]=A.a[1][0]=A.a[2][1]=1; 71 while(t--) 72 { 73 scanf("%lld",&n); 74 if(n==2) 75 { 76 pf("3 "); 77 continue; 78 } 79 ll ans=0; 80 mat tmp=pow_mod(A,n-2); 81 f(i,0,maxn-1) 82 f(j,0,maxn-1) 83 { 84 ans=(ans+tmp.a[i][j])%mod; 85 } 86 pf("%lld ",ans); 87 } 88 }