B君的第九题

B君的第九题

对于一个排列\(a_1, a_2,\dots,a_n\),如果对于一个i满足\(a_{i-1}<a_i>a_i+1\)则称i是一个极大值。我们认为\(a_0=a_{n+1}=0\)。考虑\(1,2,\dots,n\)的所有排列,问有多少个排列恰好有m个极大值。输出答案对p取模的结果。\(1\le n\le10^9, 1\le m\le10, 2\le p\le1001\)

对于统计排列数,其实没有必要按照给出的a的顺序来dp,可以先把a从小到大排序,然后用\(f[i][j]\)表示dp到第i个数,有j个山峰的方案数。由于当前数大于之前序列的所有数,考虑把它插入序列。如果它插在山峰旁边,那么山峰个数仍然不变,否则山峰个数会加一个。因此\(f[i][j]=f[i-1][j]*2j+f[i-1][j-1]*(i+1-2*(j-1))\)。

但是这个式子和i有关,没法用矩阵乘法优化dp。怎么办呢?由于所有运算都是在模p意义下的,所以说直接对于i=1到p先把矩阵暴力求出来,然后用矩阵快速幂即可!

#include <cstdio>
#include <cstring>
using namespace std;

const int maxn=1e3+5, maxm=12;
int n, m, p;
inline void up(int &x, int y){ x+=y-p; x+=(x<0?p:0); }

struct Matrix{
    int a[maxm][maxm];
}g[maxn], re, c, ans;
Matrix& operator *(const Matrix &a, const Matrix &b){
    memset(re.a, 0, sizeof(re.a));
    for (int i=0; i<=m; ++i)
        for (int j=0; j<=m; ++j)
            for (int k=0; k<=m; ++k)
            up(re.a[i][j], a.a[i][k]*b.a[k][j]%p);
    return re;
}

int main(){
    scanf("%d%d%d", &n, &m, &p);
    for (int i=0; i<=m; ++i) c.a[i][i]=1, ans.a[i][i]=1;
    for (int i=1; i<=p; ++i){
        for (int j=0; j<m; ++j){
            //if (i-2*j<0) break;  //?
            g[i].a[j][j]=2*j%p,
            g[i].a[j][j+1]=((i-2*j)%p+p)%p;
        }
        g[i].a[m][m]=2*m%p;
        c=c*g[i];
    }
    int mi=n/p;
    for (; mi; c=c*c, mi>>=1) if (mi&1) ans=ans*c;
    for (int i=1; i<=n%p; ++i) ans=ans*g[i];
    printf("%d\n", ans.a[0][m]);
    return 0;
}

原文地址:https://www.cnblogs.com/MyNameIsPc/p/9367818.html

时间: 2024-10-26 18:24:41

B君的第九题的相关文章

经典算法题每日演练——第九题 优先队列

原文:经典算法题每日演练--第九题 优先队列 前端时间玩小爬虫的时候,我把url都是放在内存队列里面的,有时我们在抓取url的时候,通过LCS之类的相似度比较,发现某些url是很重要的, 需要后端解析服务器优先处理,针对这种优先级比较大的url,普通的队列还是苦逼的在做FIFO操作,现在我们的需求就是优先级大的优先服务,要做 优先队列,非堆莫属. 一:堆结构 1:性质 堆是一种很松散的序结构树,只保存了父节点和孩子节点的大小关系,并不规定左右孩子的大小,不像排序树那样严格,又因为堆是一种完全二叉

CTF---Web入门第九题 FALSE

FALSE分值:10 来源: iFurySt 难度:易 参与人数:4567人 Get Flag:2144人 答题人数:2157人 解题通过率:99% PHP代码审计 hint:sha1函数你有认真了解过吗?听说也有人用md5碰撞o(╯□╰)o 格式:CTF{} 解题链接: http://ctf5.shiyanbar.com/web/false.php 原题链接:http://www.shiyanbar.com/ctf/1787 [解题报告] 这是我入门Web开始写的第九道题,打开解题链接,这道题

稀疏集:编程珠玑第一章第九题

<Programming Pearls> solutions for Column 1中的第9题题解 关键字: Sparse set 原题: The effect of  initializing the vector data[0..n-1] can be accomplised with a signature contained in two additional n-element vectors, from and to ,and an integer top. If the ele

第一张-第九题(关于读《构建之法》的若干疑问)

说到读书,我们组的小伙伴们都很积极,也很热情地根据本书内容并结合自身经历提出了若干问题,望老师.同学们多多赐教^_^. Question-1:如果采用MVP的方式,创意会不会有可能被其他人剽窃,让别人更早的做出完美的产品? Question-2:有时用户想要的并不符合专业人士的判断,比如用户的某个要求反而导致效率更低,那我们应该听用户的还是专家的? Question-3:个人认为软件产品是一个工程化的产品,在整个过程中,强调的是高效.可靠.功能强大及可维护性等.那么,在当今这个竞争激烈的市场中,

leetcode第九题--Palindrome Number

Problem: Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of

Leetcode第九题_Palindrome Number

Palindrome Number Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of using extra space. You could also try reversing an integer. However, if you have solved th

LeetCode 第九题, Palindrome Number

题目原文: Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of usi

第一章第九题

书中原题: 使用更多的时间来换取更少的运行时间存在一个问题:初试化空间本身需要消耗大量的时间.说明如何设计一种技术,在第一次访问向量的项时将其初始化为0.你的方案应该尽可能的使用常量的时间进行初始化和向量访问,使用的额外空间应正比于向量的大小.因为该方法 通过进一步增加空间来减少初始化时间,所以仅在空间很廉价.时间很宝贵且向量很稀疏的 情况下才考虑使用. 书后的参考答案 原文地址:https://www.cnblogs.com/DSloth/p/9191517.html

test20181017 B君的第二题

题意 分析 考场50分 旁边的L君告诉我,求的就是非升子序列的个数,于是写了个树状数组. 但是\(\mod{2333} > 0\)还需要组合数中没有2333的倍数,所以实际上只得了\(a_i \leq 2333\)的部分分,还好. #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<string