ZOJ

来源:互联网 发布:js循环数组对象 编辑:程序博客网 时间:2024/05/07 02:59

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 thesecan 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 letterCh ('A' ≤ Ch ≤ 'D'), indicate that on day ai (1 ≤ai ≤ n), group Ch is in charge of the problems. We guarantee that allai 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 21 A3 C2 11 D
Sample Output
23
Hint
Case 1:2 ways: ABC, ADC.Case 2:

3 ways: DA, DB, DC.

题意:有 n天,m个操作,  下面m行, 第一个数字是代表第几天, 然后第二个字母是哪个人出题,  一共ABCD4个人, 问有多少种方式

A C 的话 中间能填B或D 所以两种,  第二个样例 先D 后面能接 ABC  不能连续两天同一个人出题

根据递推式构造出矩阵(3,2) (0,1)

(3,2)

公式:l[i]=3*r[i-1];   l[1]=3;            r[i]=l[i-1]+2*r[i-1];  r[1]=2;

#include <vector>#include <iostream>#include <string>#include <map>#include <stack>#include <cstring>#include <queue>#include <list>#include <cstdio>#include <set>#include <algorithm>#include <cstdlib>#include <cmath>#include <iomanip>#include <cctype>#include <sstream>#include <functional>using namespace std;#define pi acos(-1)#define endl '\n'#define me(x) memset(x,0,sizeof(x));#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)typedef long long LL;const int INF=0x3f3f3f3f;const LL LINF=0x3f3f3f3f3f3f3f3fLL;const int dx[]={-1,0,1,0,-1,-1,1,1};const int dy[]={0,1,0,-1,1,-1,1,-1};const int maxn=1e3+5;const int maxx=5e4+100;const double EPS=1e-7;const int MOD=1000000007;#define mod(x) ((x)%MOD);template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;/*lch[root] = build(L1,p-1,L2+1,L2+cnt);    rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*//*lch[root] = build(L1,p-1,L2,L2+cnt-1);    rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}int n,m;struct edge{    char op;    int num;}Q[20];bool cmp(edge a,edge b){    return a.num<b.num;}struct node{    LL t[2][2];    void mex(){me(t);}}a,b,unit;node operator*(node a,node b)//重载运算符{    node ret;    LL x;    ret.mex();    for(int i=0;i<2;i++)        for(int j=0;j<2;j++)    {        x=0;        for(int k=0;k<2;k++)            x+=mod((LL)a.t[i][k]*b.t[k][j]);        ret.t[i][j]=mod(x);    }    return ret;}void init()//矩阵的初始化{    for(int i=0;i<2;i++)    {        unit.t[i][i]=1;    }    return ;}node pow_mat(node a,LL n)//矩阵快速幂{    init();    node ret=unit;    while(n)    {        if(n%2)  ret=ret*a;        a=a*a;        n>>=1;    }    return ret;}LL quick_Mod(int m)//快速幂{LL t=1;LL b=3;while(m){if(m&1) t=mod(t*b);m>>=1;b=mod(b*b);}return t;}LL 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=pow_mat(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];}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        me(Q);        for(int i=1;i<=m;i++)        {            scanf("%d %c",&Q[i].num,&Q[i].op);        }        sort(Q+1,Q+m+1,cmp);        LL ans=1;        if(m==0){printf("%lld\n",(quick_Mod(n-1)*4)%MOD);continue;}ans=mod(ans*quick_Mod(Q[1].num-1));//把前面处理了ans=mod(ans*quick_Mod(n-Q[m].num));//把后面处理了        for(int i=1;i<m;i++)        {            int cnt=Q[i+1].num-Q[i].num-1;            if(Q[i+1].op==Q[i].op)            {                if(cnt==0)                {                    ans=0;                    break;                }                else                {                    ans=mod(ans*(solve(cnt,1)));                }            }            else                ans=mod(ans*(solve(cnt,0)));        }        printf("%lld\n",ans);    }}



0 0
原创粉丝点击