2017河南工业大学校赛 F Hmz 的女装

来源:互联网 发布:qq飞车雷诺数据 编辑:程序博客网 时间:2024/06/11 14:00

问题 F: Hmz 的女装

时间限制: 2 秒  内存限制: 128 MB

题目描述

Hmz为了女装,想给自己做一个长度为n的花环。现在有k种花可以选取,且花环上相邻花的种类不能相同。
Hmz想知道,如果他要求第l朵花和第r朵花颜色相同,做花环的方案数是多少。这个答案可能会很大,你只要输出答案对10^9+7取模的结果即可。

输入

第一行三个整数n,m,k(1≤n≤100000,1≤m≤100000,1≤k≤100000)
接下来m行,每行两个整数l,r,表示要求第l朵花和第r朵花颜色相同。保证lr且 |(rlmod n| ≠1.

输出

输出m行。对于每一个询问输出一个整数,表示做花环的方案数对10^9+7取模的结果。

样例输入

8 3 21 42 61 38 3 31 42 61 3

样例输出

02260108132


解题思路:

     很经典的dp问题,因为一个环被两个相同颜色的花分成两个部分,我们取其中一个部分(不考虑两端)来看,它的两头颜色不能与两端的花相同。同时考虑两端比较难想,我们考虑固定一端,往另一端增长的情况。设置d[i][1]为长度i(都不包含固定端),第i朵花与固定端相同的方案数。d[i][0]为长度i,第i朵花与固定端颜色相同的方案数。

这时很容易推出:

               d[i][1]=d[i-1][1]*(k-2)+d[i-1][0]*(k-1)
               d[i][0]=d[i-1][1]

由于固定了两端,我们求最后一朵花与固定端颜色不同的方案。最后只需要将两部分的方案数相乘,再乘上固定端的颜色数k即可。

注意由于最后MOD 1e9+7,相乘会爆int,最后直接k乘方案数会爆long long,注意控制取模。


代码:

#include <iostream>#include<bits/stdc++.h>#define ll long longusing namespace std;const int N=210000;const ll MOD=1e9+7;ll d[N][2],k;int main(){    int n,m;    while(~scanf("%d%d%d",&n,&m,&k))    {        d[1][0]=0;        d[1][1]=k-1;        for(int i=2;i<=n;i++)        {            d[i][1]=(d[i-1][1]*(k-2)+d[i-1][0]*(k-1))%MOD;            d[i][0]=d[i-1][1];        }        for(int i=0;i<m;i++)        {            int l,r;            scanf("%d%d",&l,&r);            if(l>r) swap(l,r);            int t1=r-l-1,t2=n-t1-2;            ll ans=((k*d[t1][1]%MOD)*d[t2][1])%MOD;            printf("%lld\n",ans);        }    }}


1 0
原创粉丝点击