2018年icpc沈阳赛区C题
程序员文章站
2024-03-15 15:20:30
...
简单的计数题,题意是让你对一个1到n的一个排列执行k次插入排序,排完序以后要满足最长上升递增子序列的长度至少为n-1,问这样的排列由多少种。做的时候是这样做的,首先考虑前k个正好是前k个,然后后面的最长上升子序列大于等于n-k-1的排列的个数有多少,刚开始手推,发现推出来的公式是错误的,然后这个就打了一下表,之后考虑前面的k个有一个不属于1到k的范围以内,在纸上画了一下,发现第k个值比较特殊,多了n-k-1种,其他的都是一样就把第k+1个值插入放到前面,然后前面这个数插入到后面的空位中就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
int data[1000] = {1, 1, 2, 5, 10, 17, 26, 37, 50, 65, 82, 101, 122, 145, 170,
197, 226, 257, 290, 325, 362, 401, 442, 485, 530, 577, 626, 677, 730, 785, 842,
901, 962, 1025, 1090, 1157, 1226, 1297, 1370, 1445, 1522, 1601,
1682, 1765, 1850, 1937, 2026, 2117, 2210, 2305, 2402, 2501,
};
using ll=long long ;
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
int x=1;
ll n,k,q;
while(t--)
{
scanf("%lld%lld%lld",&n,&k,&q);
k=min(n,k);
if(k==1)
{
printf("Case #%d: %I64d\n",x++,data[n]%q);
}
else if(k==n)
{
ll ans=1;
for(ll i=1; i<=n; i++)
ans=ans*i%q;
printf("Case #%d: %I64d\n",x++,ans);
}
else
{
ll ans=1;
for(int i=1; i<=k; i++)
{
ans=ans*i%q;
}
ans = ans*(data[n-k] + k*(n-k)+n-k-1)%q;
printf("Case #%d: %I64d\n",x++,ans);
}
}
}
}
上一篇: CentOS 基础知识 Shell 基础教程1-21
下一篇: 素数筛选法
推荐阅读
-
2018年icpc沈阳赛区C题
-
【ACM-ICPC 2018 徐州赛区网络预赛】H题 Features Track ---- 树状数组
-
ACM-ICPC 2018 沈阳赛区网络预赛 F题 Fantastic Graph
-
ACM-ICPC 2018 沈阳赛区网络预赛-Made In Heaven-K短路
-
ACM-ICPC 2018 沈阳赛区网络预赛 - K Supreme Number - 推理
-
ACM-ICPC 2018 沈阳赛区网络预赛 K. Supreme Number(打表找规律)
-
ACM-ICPC 2018沈阳赛区网络预赛 K题
-
ACM-ICPC 2018 沈阳赛区网络预赛(待更新)
-
ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven(A*,K短路)
-
ACM-ICPC 2018 徐州赛区网络预赛A题