这是一道智障题

这是一道智障题

题目链接:http://acm.xidian.edu.cn/problem.php?id=1180

dp+矩阵快速幂

这道题的n为1e18,故复杂度为O(1)或者O(lgn)。比赛的时候只看出了是dp,感觉复杂度太高,没想到用矩阵来优化,gg。

先来定义状态:dp[i][j][k]表示取第i个珠子颜色为j且末尾有k个连续的珠子的总数,

转移方程:

当k=1时,dp[i][j][k]=dp[i-1][不为j的颜色][所有k];

当k!=1时,dp[i][j][k]=dp[i-1][j][k-1].

但是这样一来,无论是时间复杂度还是空间复杂度都过大,必须优化。

考虑到不管j取何值,对于相同的i和k来说,dp[i][j][k]一定相同(对称性),所以dp[i][j][0]=dp[i-1][j][所有k]*(m-1),

如此,可以构造转移矩阵

matrix=[[m-1,m-1,...,m-1,m-1],[1,0,...,0,0],[0,1,...,0,0],...,[0,0,...,1,0]].

初始状态为[1,0,0,...,0,0]^(-1).

(比较神奇的是,编译的时候遇到了编译器错误:internal compiler error: Segmentation fault,人品简直不要太好= =)

代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #define N 100
 4 #define M 23333
 5 using namespace std;
 6 typedef long long LL;
 7 LL n,m,k;
 8 struct matrix{
 9     LL mp[N][N];
10     matrix mul(matrix A){
11         matrix temp;
12         for(int i=0;i<k;++i)
13         for(int j=0;j<k;++j){
14             temp.mp[i][j]=0;
15             for(int t=0;t<k;++t){
16                 LL r=(mp[i][t]*A.mp[t][j])%M;
17                 temp.mp[i][j]=(temp.mp[i][j]+r)%M;
18             }
19         }
20         return temp;
21     }
22 };
23 matrix pow(matrix E,matrix A,LL n){
24     while(n){
25         if(n&1)E=E.mul(A);
26         A=A.mul(A);
27         n>>=1;
28     }
29     return E;
30 }
31 matrix e,a;
32 int main(void){
33     for(int i=0;i<N;++i)e.mp[i][i]=1;
34     for(int i=1;i<N;++i)a.mp[i][i-1]=1;
35     while(~scanf("%lld%lld%lld",&n,&m,&k)){
36         k--;
37         for(int i=0;i<k;++i)a.mp[0][i]=m-1;
38         matrix temp=pow(e,a,n-1);
39         LL ans=0;
40         for(int i=0;i<k;++i)ans=(ans+temp.mp[i][0])%M;
41         ans=(ans*m)%M;
42         printf("%lld\n",ans);
43     }
44 }
时间: 2024-10-10 02:40:06

这是一道智障题的相关文章

SCOI 2018 划水记

(此处不应有目录,省选爆零的过程得慢慢看) Day -n 一诊 说真的,在没看到“第一次诊断性考试”之前,一直以为是“一整”,真是可怕,初中教育都开始像UW中的最高祭司学习了. 感觉题目很gg.于是考5科挂5科,什么,学校还要加餐?考史政体?好可怕啊. 数学考试挂掉以后,后面的科目有点小绝望.物理28道智障题我竟读错25题3遍,浪费我10分钟? 数学考试有3道题真是骚.全班考场上没有一个人做起.27题第二问班主任不会做?Excuse me? 更有趣的是,下来我和某个同学想出了同一个27题第二问的

Benelux Algorithm Programming Contest 2014 Final ACM-ICPC Asia Training League 暑假第一阶段第二场 E. Excellent Engineers-单点更新、区间最值-线段树 G. Growling Gears I. Interesting Integers-类似斐波那契数列-递推思维题

先写这几道题,比赛的时候有事就只签了个到. E. Excellent Engineers 传送门: 这个题的意思就是如果一个人的r1,r2,r3中的某一个比已存在的人中的小,就把这个人添加到名单中. 因为是3个变量,所以按其中一个变量进行sort排序,然后,剩下的两个变量,一个当位置pos,一个当值val,通过线段树的单点更新和区间最值操作,就可以把名单确定. 代码: 1 //E-线段树 2 #include<iostream> 3 #include<cstdio> 4 #incl

【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA

传送门 写在前面:一天下来就写了两道主席树的题--(codevs上的一道智障天梯不算) 思路: 才知道原来主席树不仅可以通过dfs序维护子树区间,还可以直接维护一条到根的链-- 我们建好主席树后,每次查询u->v路径上的第k大,无非有两种情况 1.u,v在同一条链上 2.u,v不在同一条链上 其实这两种情况处理起来是一样的,我们利用主席树中的前缀和思路,root[u]并上root[v]再减去root[lca(u,v)]再减去root[fa[lca(u,v)]]就是u->v路径上的点了(可以自己

【NOIP2016】组合数问题

题目描述 Description 输入描述 Input Description 从标准输入读入数据. 第一行有两个整数 t,k,其中 t 代表该测试点总共有多少组测试数据,k 的意义见问题描述. 接下来 t 行每行两个整数 n,m,其中 n,m的意义见问题描述. 输出描述 Output Description 输出到标准输出. tt 行,每行一个整数代表所有的 0≤i≤n,0≤j≤min(i,m) 中有多少对 (i,j)(满足 Cji 是 k 的倍数. 样例输入 Sample Input 1 2

猴子分桃问题的解决方法

猴子分桃问题的解决方法 1 问题 1979年,李政道博士给中国科技大学少年班出过一道智趣题:5只猴子分一堆桃子,怎么也分不成5等分,只好先去睡觉,准备第二天分.夜里1只猴子偷偷爬起来,先吃掉一个桃子,然后将其分为5等份,藏起自己的一份就去睡觉了:第二只猴子又爬起来,吃掉一个桃子后,也将桃子分成5等份,藏起自己的一份睡觉去了:以后的3只猴子都先后照此办理.问最初至少有多少个桃子? 现在考虑更加的一般性,说是m只猴子,问最初最少有多少个桃子? 2 解答: 2.1 递推解法 设最初有x个桃子,猴子的个

SHTSC2017酱油记~~~

一转眼,SHTSC2017就结束了呢... [前记] noip2016的时候,day2由于各种奇奇怪怪的原因,于是策略上犯错误,然后直接滚粗... 作为一个SHTSC2016年就莫名其妙当上B队队长的人...这个rank5简直是不能看... 于是就开始努力啊,我要翻进A队啊... 然后一转眼,大半年就过去了... day1 矣?这不是cxm老师嘛---exciting--- 拿到卷子了...这个T2...相逢是问候...一看题目就很厉害啊... T1感觉是个网络流?(我当时在干什么啊qwq) T

2017Summmer_上海金马五校 F题,G题,I题,K题

以下题目均自己搜 F题  A序列 一开始真的没懂题目什么意思,还以为是要连续的子串,结果发现时序列,简直智障,知道题意之后,好久没搞LIS,有点忘了,复习一波以后,直接双向LIS,处理处两个数组L和R,然后对整个数组扫一遍对于每一个下标取m=min(L[i],R[i]);用ans取2*m-1中的最大值.LIS用nlogn的算法实现,二分用的是lower_bound(),直接看代码. //Author: xiaowuga #include <bits/stdc++.h> #define maxx

AC日记——[网络流24题]骑士共存 cogs 746

746. [网络流24题] 骑士共存 ★★☆   输入文件:knight.in   输出文件:knight.out   简单对比时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一行

刷题总结——弹飞绵羊(bzoj2002)

题目: Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞.绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞.为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数. Input