2018 宁夏邀请赛 I - Bubble Sort(感谢q神的题解

题意:

Bubble sort is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted.

Izdihar is an ACM-ICPC master and provides a pseudocode implementation about the bubble sort for you. The algorithm for a list of sortable items A can be expressed as (1-based array):

  1. n = length(A)
  2. repeat
    1. swapped = false
    2. for i = 2 to n inclusive do
      1. if A[i-1] > A[i] then
        1. swap( A[i-1], A[i] )
        2. swapped = true
        end if
      end for
    until not swapped

She says a permutation of $$$1$$$ to $$$n$$$ is almost sorted if the length of its longest increasing subsequence is at least $$$n-1$$$.

You are asked to count the number of permutations of $$$1$$$ to $$$n$$$ which, after $$$k$$$ times passing through the list in the bubble sort, would become an almost sorted permutation.

问k次后一个1到n的序列的所有全排列有多少被排好序了,称一个序列排好序,是这个序列的LIS>=n-1。

这个题很难,gym上这题毛子那边出了三个队,中国出了一个队,但是代码短小精悍。

一个易证的事实:冒泡k次后一个序列的后k个数一定排好序了,对于冒泡k次后的新序列,第i位的数一定是原序列前min(i+k,n)个未在原序列中前i-1位出现的数,意味着新序列第i个数在原序列有k+1种位置。

一个序列的LIS>=n-1相当于将一个序列的某个区间想左或右循环移动。

那么我们就可以计数了:我们枚举新序列的每个数在原序列的位置。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int T,n,k,mod;
LL bit[55];
int main()
{
    scanf("%d",&T);
    for (int z=1;z<=T;++z)
    {
        scanf("%d%d%d",&n,&k,&mod);
        printf("Case #%d: ",z);
        if (k>=n)
        {
            LL ans=1;
            for (int i=1;i<=n;++i) ans=ans*i%mod;
            printf("%lld\n",ans);
            continue;
        }
        bit[0]=1;
        for (int i=1;i<=n;++i) bit[i]=1LL*bit[i-1]*(k+1)%mod;
        LL ans=0;
        //sorted
        ans=bit[n-k];
        //left shift
        for (int len=2;len<=n-k;++len) 
            ans+=1LL*(n-k-len+1)*bit[n-k-1]%mod,ans%=mod;
        //right shift
        for (int len=3;len<=n-k;++len) 
        ans+=1LL*(n-k-len+1)*bit[n-k-len+1]%mod,ans%=mod;
        //last k
        for (int i=1;i<=k;++i) ans=ans*i%mod;
            printf("%lld\n",ans);
    }
    return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值