【题目描述】一个2*i的矩阵,一共有m种颜色,相邻两个格子颜色不能相同,m种颜色不必都用上,f[i]表示这个答案,求Σf[i]*(2*i)^m (1<=i<=n)%p。

  【数据范围】

    20% n,m<10^5 p<10^9

    其余 n<10^9

      其中40% m<100 p<10^9

        20% m<10^3 p<10^9

        20% m<10^4 p<10^3

  首先我们可以推导出f[i]的式子,f[1]=m*(m-1),因为其余的格子,我们第一个格子可以放m-1种颜色,第二个格子在第一个格子和上一层第二个格子颜色不同时有m-2种情况,相同时有m-1种情况,那么我们可以得出f[i]=f[i-1]*(m^2-3*m+3),设a=m^2-3*m+3,那么问题就变成了求2^m*m*(m-1)/a*Σa^i*i^m (1<=i<=n)。

  对于前20%的数据,我们可以暴力的nlogm递推求解。

  对于中间的20%数据,我们可以化简一下求解式。

    设w[i][j]为Σa^j*j^k (1<=j<=i),那么答案就成了2^m*m*(m-1)/a*w[n][m],现在的问题就是求解w[n][m]。

    w[n][m]=Σa^i*i^m (1<=i<=n),w[n+1][m]=Σa^i*i^m (1<=i<=n+1)=a+Σa^i*i^m (2<=i<=n+1)=a+a*Σa^i*(i+1)^m (1<=i<=n)

    那么我们可以根据二项式展开来化简,w[n+1][m]=a+a*Σa^iΣc(m,j)*i^j (1<=i<=n) (0<=j<=m)=a+a*Σc(m,j)*w[n][j] (0<=j<=m),那么这样我们就可以写一个矩阵来加速在n^3logn的时间内求解了。

  对于m<10^3的情况,w[n+1][m]=w[n][m]+a^(n+1)*(i+1)^m。根据刚才的推导,w[n+1][m]=a+a*Σc(m,j)*w[n][j] (0<=j<=m)。所以我们可以得到

    w[n][m]+a^(n+1)*(i+1)^m=a+a*Σc(m,j)*w[n][j] (0<=j<=m),这样我们发现,如果我们知道了w[n][m]之前的w[n][j],那么我们可以在m的时间内反解出w[n][j]。

  对于最后的20%,我们发现p非常小,考虑答案的求和式Σa^i*i^m,发现这个式子之和i和i^m有关,当i,i^m和j,j^m关于mod p相等之后,那么i与j之后的变换是相同的,我们可以发现一共有p^2个不同的情况,那么我们记下来这个循环之后就可以算出来了。

//By BLADEVIL
#include <cstdio>
#define LL long long
#define maxp 1010
#define maxm 1010 using namespace std; int n,m,p,a;
int mo[maxp],next[maxp],w[maxm],c[maxm][maxm];
int flag[maxp][maxp],f[maxp*maxp],g[maxp*maxp]; int mi(int a,int k) {
int ans=;
while (k) {
if (k&) ans=((LL)ans*a)%p;
a=((LL)a*a)%p;
k>>=;
}
return ans;
} void work1() {
int ans=;
ans=((LL)m*(m-))%p; ans=((LL)ans*mi(,m))%p;
ans=((LL)ans*mi(a,p-))%p; //printf("%d\n",ans);
int cur=;
for (int i=;i<=n;i++) cur=((LL)cur+(LL)mi(a,i)*mi(i,m))%p;
ans=((LL)ans*cur)%p;
printf("%d\n",ans);
} void work2() {
int i,l,r;
f[]=(LL)m*(m-)%p; g[]=(LL)f[]*mi(,m)%p;
flag[][f[]]=;
for (i=;i<=n;i++) {
f[i]=(LL)f[i-]*a%p;
g[i]=(LL)f[i]*mi(*i,m)%p;
if (flag[i%p][f[i]]) {
l=flag[i%p][f[i]];
r=i-;
break;
}
flag[i%p][f[i]]=i;
}
//printf("%d %d %d %d\n",l,r,i,g[i]);
int len=r-l+,ans=,tmp=;
for (int j=;j<l;j++) ans=(ans+g[j])%p;
n-=l-;
for (int j=l;j<=r;j++) tmp=(tmp+g[j])%p;
ans=(ans+(LL)tmp*(n/len)%p)%p;
for (int j=;j<=n%len;j++) ans=(ans+g[l+j-])%p;
printf("%d\n",ans);
} void work3() {
for (int i=;i<=m;i++) {
c[i][]=c[i][i]=;
for (int j=;j<i;j++) c[i][j]=(c[i-][j]+c[i-][j-])%p;
}
int ans=;
ans=((LL)m*(m-))%p; ans=((LL)ans*mi(,m))%p;
ans=((LL)ans*mi(a,p-))%p; //printf("%d\n",ans);
//for (int i=1;i<=m;i++) printf("%d ",c[m][i]); printf("\n");
w[]=((LL)mi(a,n+)-a+p)%p; w[]=((LL)w[]*mi(a-,p-))%p;
//printf("%d\n",w[0]);
for (int i=;i<=m;i++) {
w[i]=((LL)mi(a,n+)*mi(n+,i)-a+p)%p;
for (int j=;j<i;j++) w[i]=((LL)w[i]-((LL)a*c[i][j]%p*w[j]%p)+p)%p;
w[i]=(LL)w[i]*mi(a-,p-)%p;
w[i]%=p;
}
//printf("%d\n",w[m]);
ans=((LL)ans*w[m])%p;
printf("%d\n",ans);
} int main() {
freopen("color.in","r",stdin); freopen("color.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
a=((LL)m*m-*m+)%p;
if (n<=) work1(); else
if (m>) work2(); else work3();
fclose(stdin); fclose(stdout);
return ;
}

【HNOI】矩阵染色 数论的更多相关文章

  1. 【BZOJ3243】【NOI2013】向量内积(矩阵,数论)

    [BZOJ3243][NOI2013]向量内积(矩阵,数论) 题面 BZOJ 题解 这题好神仙. 首先\(60\)分直接是送的.加点随机之类的可以多得点分. 考虑正解. 我们先考虑一下暴力. 我们把\ ...

  2. 矩阵乘法快速幂 codevs 1250 Fibonacci数列

    codevs 1250 Fibonacci数列  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 定义:f0=f1=1 ...

  3. Codevs 1287 矩阵乘法&&Noi.cn 09:矩阵乘法(矩阵乘法练手题)

    1287 矩阵乘法  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 小明最近在为线性代数而头疼, ...

  4. Codevs 1305 Freda的道路(矩阵乘法 DP优化)

    1305 Freda的道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description Freda要到Rainbow的城堡去玩了.我们可以认 ...

  5. Codevs 1482 路线统计(矩阵乘法)

    1482 路线统计 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description N个节点的有向图, 求从start到finish刚好经过时 ...

  6. Codevs 1070 普通递归关系(矩阵乘法)

    1070 普通递归关系 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 考虑以下定义在非负整数n上的递归关系 f(n) = f0 ...

  7. 1250 Fibonacci数列(矩阵乘法)

    1250 Fibonacci数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 定义:f0=f1=1, fn=fn-1+fn ...

  8. Codevs 1574 广义斐波那契数列(矩阵乘法)

    1574 广义斐波那契数列 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 广义的斐波那契数列是指形如an=p*an-1+q* ...

  9. Codeforces Round #344 (Div. 2) B. Print Check

    B. Print Check time limit per test 1 second memory limit per test 256 megabytes input standard input ...

随机推荐

  1. OSG学习:基本几何体绘制示例

    绘制并渲染几何体主要有如下3大步骤: 1.创建各种向量数据,如顶点.纹理坐标.颜色和法线等.需要注意的是,添加顶点数据时主要按照逆时针顺序添加, 以确保背面剔除的正确. 2.实例化一个几何体对象(os ...

  2. 3ds Max学习日记(二)

      搞了一天终于把第二章弄完了,虽然有点慢,但也是没有办法,毕竟中途学累了总得放松一下吧.   又get到了一个新知识点,是关于3ds max的捕捉工具的,详情见3DS MAX 学习笔记 一(捕捉工具 ...

  3. C语言的世界

    大家好,我是一名大一的学生,我叫陈由钧,我来自计算机系,一开始选择这门专业的时候,是出于对计算机的热爱,我喜欢计算机,喜欢没事琢磨琢磨计算的各种程序,各种软件,所以我选择学习计算机这门专业,第一周我就 ...

  4. c#控件的name和text属性有什么不同?

    text 是显示出来,供用户和自己编辑方便使用的,name 属性是编辑代码用的. 比如要读取一个text栏的内容 取name='txtName' text='姓名'代码段需要写的是, txtName. ...

  5. 织梦CMS建站入门学习(一)

    一.下载与安装. 首先到织梦官网下载软件,可选择UTF8或GBK不同编码格式,如果电脑没有PHP环境,还要下载dede自带的PHP环境软件. 将软件中的upload文件夹内容复制到WWW文件夹下,然后 ...

  6. [剑指Offer] 55.链表中环的入口结点

    题目描述 一个链表中包含环,请找出该链表的环的入口结点. [思路]根据set集合的不重复,遍历链表时遇到的第一个重复结点就是环的入口结点. /* struct ListNode { int val; ...

  7. XML-RPC协议学习

    XML-RPC调用包括2部分:客户端client(调用线程).服务器端server(被调用的线程).服务端是通过特定的URL获得的,调用过程如下: 1.客户端程序使用XML-RPC客户端发出作业请求, ...

  8. Git更新github项目

    1. 把github上你想要更新修改的项目克隆到本地 $ git clone https://github.com/delav/test.git 2. 根据自己需求对项目进行修改 3. 把项目放到缓存 ...

  9. [POI2014]FAR-FarmCraft 树形DP + 贪心思想

    (感觉洛谷上题面那一小段中文根本看不懂啊,好多条件都没讲,直接就是安装也要一个时间啊,,,明明不止啊!还好有百度翻译......) 题意:一棵树,一开始在1号节点(root),边权都为1,每个点有点权 ...

  10. spring任务执行器与任务调度器(TaskExecutor And TaskScheduler)

    对于多线程及周期性调度相关的操作,spring框架提供了TaskExecutor和TaskScheduler接口为异步执行和任务调度.并提供了相关实现类给开发者使用.(只记录采用注解的使用形式,对于X ...