zoj 3538 Arrange the Schedule

Arrange the Schedule


Time Limit: 1 Second      Memory Limit: 65536 KB



In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group
in charge of the training problems on each day. As the ICPC Team manager, you have to decide which team is in charge of the problems on each day. But there are something you should rememeber:

1. No team is able to provide problems on two adjacent days.

2. There are m days in the Summer 2011 that which group is in charge of the problems have been decided. (e.g. Akiba provides problems on day 1, BiliBili provides problems on day 6. And these can not be changed)

How many ways are there to arrange the schedule? Output the answer modulo 1000000007.

Input

There are multiple test cases(less than 50). Each case contains two integers n, m (1 ≤ n ≤ 10000000, 0 ≤ m ≤ 10), which indicate the number of days in
Summer 2011 and the number of days that have been decided.

Following m lines. Each line contains one integer ai and one upper letter Ch (‘A‘ ≤ Ch ≤ ‘D‘), indicate that on day ai (1 ≤ ai ≤ n), group Ch is in charge of the problems. We guarantee
that all ai are distinct. There is a blank line after each input case.

Output

For each case, output a single line containing the answer, the number of the ways to arrange the schedule modulo 1000000007.

Sample Input

3 2
1 A
3 C

2 1
1 D

Sample Output

2
3

Hint

Case 1:
2 ways: ABC, ADC.
Case 2:
3 ways: DA, DB, DC.

题解:

大致的意思就是说给定n天,每天从A,B,C,D里面挑一个字母放进去,使得相邻的字母不相同,题目规定给定特定的m天,这m天的字母已经给定,并且不能修改,问不同的放置方法。

首先想到的就是推公式,那么我来讲一下我的思路:

首先假设n=3,m=2(d=n-m=1),那么规定为第一天为A,第三天为A;

1.就是这个样子    A__A ,那么第二天  的 填冲方法就是三种 B,C,D;-------用l[d=1]来代表,那么l[1]=3;

2.那么假设  第三天是 B,也就是 A__B  ,那么 第二天的填充方法就是两种 C,D;-------用r[d=1]来代表,那么r[1]=2;

上面的例子中1代表的是相邻的规定的两个字母是相同的情况(A=A),而2代表的是不同的情况(A!=B)。

然后假设n=4,m=2(d=n-m=2),那么规定为第一天为A,第四天为A;

就是这个样子    A____A ,那么第二天  的 填冲方法就是三种 B,C,D,那么第三天呢?此时,先来看一下,第二天的三种情况B,C,D,与第四天均是不相同的,那么这时就可以从d=2的情况转化到d=1的2的情况(也就是A!=B的情况);---------l[d=2]=3*r[1];

那么假设  第四天是 B,也就是 A____B  ,那么 第二天的填充方法就是两种B,C,D,那么第三天呢?此时,先来看一下,假设第二天是B,那么就转化成d=1的1的情况,假设第二天是C,D,那么就转化成d=1的2的情况;---------r[d=2]=l[1]+2*r[1];

----------

-------

这样以此类推.....

这样就能总结出公式:l[i]=3*r[i-1];   l[1]=3;

r[i]=l[i-1]+2*r[i-1];  r[1]=2;

如果会母函数的话,那么可以推倒一下计算公式。这里不介绍推导公式的做法了,下面介绍的是矩阵快速幂的做法。

由于题目中的n是10^7的,所以使用两个数组打表记录的话会爆内存,所以用矩阵快速幂来计算还是比较合适的。

够造a矩阵| 3  2 |      b矩阵 | 0  1 |

| 3  2 |

那么只需要计算 b矩阵的 幂就可以了啊。

注意:当给定的某两天相邻且字母相同时,输出0。

区间两侧的情况和m=0的情况单独处理。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define p 1000000007
using namespace std;

struct mat
{
    long long t[2][2];
    void set()
    {
        memset(t,0,sizeof(t));
    }
} a,b;

mat multiple(mat a,mat b)
{
    int i,j,k;
    mat temp;
    temp.set();
    for(i=0; i<2; i++)
        for(j=0; j<2; j++)
        {
                for(k=0; k<2; k++)
                    temp.t[i][j]=(temp.t[i][j]+a.t[i][k]*b.t[k][j])%p;
        }
    return temp;
}

mat quick_mod(mat b,int m)
{
    mat t;
    t.set();
    for(int i=0; i<2; i++) t.t[i][i]=1;
    while(m)
    {
        if(m&1)
        {
            t=multiple(t,b);
        }
        m>>=1;
        b=multiple(b,b);
    }
    return t;
}

long long quick_Mod(int m)
{
    long long t=1;
    long long b=3;
    while(m)
    {
        if(m&1) t=t*b%p;
        m>>=1;
        b=b*b%p;
    }
    return t;
}

long long solve(int m,int c)
{
    if(m<=0) return 1;
    b.t[0][0]=0;
    b.t[0][1]=1;
    b.t[1][0]=3;
    b.t[1][1]=2;
    a=quick_mod(b,m-1);
    if(c==1) return 3*a.t[0][0]+2*a.t[1][0];
    return 3*a.t[0][1]+2*a.t[1][1];
}
struct node
{
    int q;
    char s[3];
}t[12];
bool cmp(node a,node b)
{
    return a.q<b.q;
}
int main()
{
    int n,m;

    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int sum1=0,sum2=0;
        long long ans=1;
        if(m==0)
        {
            printf("%lld\n",quick_Mod(n-1)*4%p);
            continue;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%s",&t[i].q,t[i].s);
        }
        sort(t,t+m,cmp);
        ans=ans*quick_Mod(t[0].q-1)%p;
        ans=ans*quick_Mod(n-t[m-1].q)%p;
        for(int i=0;i<m-1;i++)
        {
            if(t[i].s[0]==t[i+1].s[0])
            {
               sum1=t[i+1].q-t[i].q-1;
               if(sum1==0)
               {
                   ans=0;
                   break;
               }
               else
                ans=ans*solve(sum1,1)%p;
            }

            else sum2=t[i+1].q-t[i].q-1,ans=ans*solve(sum2,0)%p;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

zoj 3538 Arrange the Schedule

时间: 2024-09-29 19:24:02

zoj 3538 Arrange the Schedule的相关文章

zoj 3538 Arrange the Schedule(矩阵快速幂)

Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in c

zoj 3538 递推

题目连接:Click here Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There

【dp】Arrange the Schedule

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3538 题意:如题. 题解: 假如 一组数据 ...(n1)A....(n2)A....(n2)   由于三部分为独立事件, 则总数为三部分相乘. (1)(3)易求,即3^n1, 3^n3,对于 (2), 当头尾相同(如样例) 可推出 an = 2an - 1 + 3an - 2; (a1 = 0, a2 = 3) 则 an =( 3(-1)^(n - 2) +

zoj - 3538(矩阵乘法)

题目链接:here—————— 题意:有四个人 A,B,C,D 每天出一套卷子,相邻的两天不能由同一个人出题 给你两个数n,m分别表示n天和m个操作(把第ai天定为有bi出题) 问有多少种方式?? 题解:  先排序 if  bi == bi-1 && ai - ai-1 = 1     return 0;  if       bi == bi-1  设f1 = 3:fn = 3^n - fn-1; else    f1 = 2;fn = 3^n - fn-1; 再判断两头 矩阵    -1

poj3683 2-SAT 同上一道

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10151   Accepted: 3475   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old l

POJ 3683(Priest John&#39;s Busiest Day-强连通分量解决2-SAT)[Template:2-SAT]

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8144   Accepted: 2769   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old le

POJ 3683.Priest John&#39;s Busiest Day 2-SAT

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10144   Accepted: 3472   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old l

Soj题目分类

-----------------------------最优化问题------------------------------------- ----------------------常规动态规划  SOJ1162 I-Keyboard  SOJ1685 Chopsticks SOJ1679 Gangsters SOJ2096 Maximum Submatrix  SOJ2111 littleken bg SOJ2142 Cow Exhibition  SOJ2505 The County

图论(2-sat):Priest John&#39;s Busiest Day

Priest John's Busiest Day Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old legend in the town that the couple who get married on that day will be forever blessed by the God of