BZOJ(本校) 3048 染色 - dp&递推找规律

【问题描述】
最近大大很happy,她制作了一些小旗,小旗都排成一列。现在她有四种颜色,分别为R,B,W,Y。突发奇想的大大决定出个问题考考你。她想知道,n面小旗染色有多少种不同的方案数。这样太简单了,答案不就是4^n么。于是她加了点限制,有5个限制条件,分别要求
1、相邻两面旗染色不相同
2、R,B两种颜色不能相邻
3、Y,W两种颜色不能相邻
4、R,W,B不能在一起。即不能出现连续三个是RWB的排列。
5、正反一样的算一种
但是大大觉得这样还是太简单了,于是她定义f(n)为n面红旗的方案数,她给你L和R两个正整数,让你计算Ri=Lf(i),但是由于答案太大,你只需要mod 1000000007即可。
求答案。

【输入格式】
共一行两个正整数L和R,保证L<=R。

【输出格式】
输出只有一行,一个整数。

【样例输入输出1】
3 4
///
23
对于样例一的解释:
3面小旗:BWB, BYB, BYR, RWR, RYR, WBW, WBY, WRW, WRY, YBY, YRY (11 种)。
4面小旗: BWBW, BWBY, BYBW, BYBY, BYRW, BYRY, RWRW, RWRY, RYBW, RYBY, RYRW, RYRY (12 种)。
所以答案为11+12=23种。

【样例输入输出2】
5 6
///
64

【数据范围】
对于10%的数据,有1<=L<=R<=10
另有40%的数据,有 R-L+1<=10
对于100%的数据,1<=L<=R <=1000000000

分析:

  • 先写个满足1-4条件的dp,如果长度为偶数,一定满足条件5(相邻两个不能相等),f(len)=dp(len)/2;如果长度为奇数,f(len)=(dp(len)-dp(len/2+1))/2+dp(len/2+1) ,因为本身回文的只出现了一次,所以要再加上本身回文的。
  • 将dp值打个表,发现单从奇数位置或偶数位置看,竟然是等比数列!
    那么耐着性子用等比求和公式推一推就出来了,具体看程序吧。
#include<cstdio>
#include<algorithm>
using namespace std;
#define Mod 1000000007

int phi;
void exgcd(int a,int b,int &d,int &x,int &y)
{
    if(!b){
        d=a;
        x=1,y=0;
        return ;
    }
    exgcd(b,a%b,d,y,x);
    y=1LL*y-(a/b)*x;
}
int Inv(int a,int b)
{
    int d,x,y;
    exgcd(a,b,d,x,y);
    return (1LL*x%Mod+Mod)%Mod;
}
int mypow(int x,int k)
{
    int ret=1;
    x%=Mod;
    while(k){
        if(k&1)
            ret=1LL*ret*x%Mod;
        x=1LL*x*x%Mod;
        k>>=1;
    }
    return ret;
}
int sigma_pw(int q)
{
    int r=mypow(3,q+1)%Mod;
    return ((1LL*r-1+Mod)%Mod*phi)%Mod;
}
int Line(int t)
{
    int p=t,q=t-1;
    if(t%2) swap(p,q);
    return (1LL*8*(sigma_pw(p/2-1)%Mod)%Mod+1LL*14*(sigma_pw(q/2-1)%Mod)%Mod)%Mod;
}
int Getans(int n)
{
    if(n==0) return 0;
    if(n==1) return 4;
    int p1=Line(n)%Mod,p2=Line(n%2==0?n/2:(n/2+1))%Mod;
    return ((((1LL*(p1-p2)%Mod+Mod)%Mod*phi)%Mod+p2)%Mod+(n>=1?1:0)*4)%Mod;
}
int main()
{
    int L,R;
    scanf("%d%d",&L,&R);
    phi=Inv(2,Mod)%Mod;
    int p=Getans(R),q=Getans(L-1);
    printf("%d\n",(int)((1LL*(p-q)%Mod+Mod)%Mod));
}
posted @ 2016-03-07 17:43  KatarinaYuan  阅读(260)  评论(0编辑  收藏  举报