zoukankan      html  css  js  c++  java
  • [提高组集训2021] 就差⼀点

    一、题目

    对一个长度为 (n) 的排列冒泡排序,给定参数 (k),问有多少排列排序后存在一个大小为 (n-1) 的上升子序列。

    for(int i=1;i<=k;i++)
    	for(int j=1;j<n;j++)
    		if(p[j]>p[j+1]) swap(p[j],p[j+1])
    

    (nleq 5000)

    二、解法

    首先介绍一下反序表,解决排列问题的又一利器 ( t get)

    定义:定义数组 (d_i=sum_{j=1}^{i}[p_j<p_i]) 表示排列 (p) 的反序表,当然也可以定义成 (d_{p_i}=sum_{j=1}^i[p_j<p_i])

    性质1:反序表和排列构造双射,因为反序表可以通过插入法构造出对应的排列。

    性质2:一个排列被冒泡排序的次数是 (max d_i)每次冒泡把 (d_i) 中的非 (0) 元素减 (1) 然后前移一位。


    本题套用上面的结论即可,首先我们考虑能被排好序的排列个数怎么求,其实就是反序表前 (k) 个元素任意取值,后 (n-k) 个元素只能取 ([0,k]),方案是 (k! imes(k+1)^{n-k}),我们把没被排好序的方案分成两种情况:

    情况1:排序后反序表为:(00..011110..00),也就是中间出现了连续的一段 (1),那么这段 (1) 初始的元素值一定是 (k+1),我们枚举这一段 (1) 的长度,可以得到初始反序表的方案数是:

    [k!sum_{i=1}^{n-k-1}(k+1)^{n-k-i} imes(n-k-i) ]

    情况2:排序后反序表为:(00..00x00..00),其中 (x>1),我们枚举它初始的位置是 (i+k),那么初始反序表的方案数是:

    [k!sum_{i=3}^{n-k}(i-2) imes(k+1)^{n-k-1} ]

    把所有情况的方案加起来即可。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    #define int long long
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int T,n,m,k,pw[5005];
    signed main()
    {
    	//freopen("almostthere.in","r",stdin);
    	//freopen("almostthere.out","w",stdout);
    	T=read();
    	while(T--)
    	{
    		n=read();k=read();m=read();
    		pw[0]=1;k=min(k,n);
    		for(int i=1;i<=n;i++)
    			pw[i]=pw[i-1]*(k+1)%m;
    		int ans=pw[n-k];
    		for(int i=1;i<n-k;i++)
    			ans=(ans+(n-k-i)*pw[n-k-i])%m;
    		for(int i=3;i<=n-k;i++)
    			ans=(ans+(i-2)*pw[n-k-1])%m;
    		for(int i=1;i<=k;i++)
    			ans=ans*i%m;
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    心态--编程+成长
    【Oracle】容易犯的错误和技巧集合
    【WPF】DataGrid的Row样式设置
    【WPF】给TextBox添上Label
    【Oracle】异常信息的加工处理
    【.Net 】Json和Xml解析
    【Win32 API】利用SendMessage实现winform与wpf之间的消息传递
    【WCF】利用WCF实现上传下载文件服务
    【Oracle】实现Oracle数据库对象的一键升级
    感触
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/15249814.html
Copyright © 2011-2022 走看看