Codeforces Round #326 (Div. 1) B Duff in Beach
2015-11-08 18:19
435 查看
B.Duff in Beach
题意:有一个长为l的序列B是由一个长度为n的序列A循环得到的,即bi=ai mod n,现在定义一个新的序列C,C的生成条件有三个:
1.C中每个元素都在B中,并且C中的每个元素都在不同的循环节里(即C中两个相邻的元素在B中的距离不会超过2n,不会低于n);
2.C的长度超过k;
3.C不递减。
问C有多少种,答案模1e9+7。
思路:
先把B分成两组,一组长度是⌊ln⌋∗n, 另一组就是l mod n。
对于第一组,因为C是不递减序列而且元素不在同一循环节里,所以可以对A排序,这样只要ai≤aj,那么在下个循环节里aj就可以接在ai后面。
用dp[i][j]表示C的长度为i,以不超过j结尾时所有可能的C序列的数量。
在i≤k时,对于dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]);
在i>k时,ans的增量是dp[k][max{ai}]。
对于第二组,要判断加上这部分长度会不会超过k,ans的增量在dp里找就可以了。
时间复杂度O(nk)。
题意:有一个长为l的序列B是由一个长度为n的序列A循环得到的,即bi=ai mod n,现在定义一个新的序列C,C的生成条件有三个:
1.C中每个元素都在B中,并且C中的每个元素都在不同的循环节里(即C中两个相邻的元素在B中的距离不会超过2n,不会低于n);
2.C的长度超过k;
3.C不递减。
问C有多少种,答案模1e9+7。
思路:
先把B分成两组,一组长度是⌊ln⌋∗n, 另一组就是l mod n。
对于第一组,因为C是不递减序列而且元素不在同一循环节里,所以可以对A排序,这样只要ai≤aj,那么在下个循环节里aj就可以接在ai后面。
用dp[i][j]表示C的长度为i,以不超过j结尾时所有可能的C序列的数量。
在i≤k时,对于dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]);
在i>k时,ans的增量是dp[k][max{ai}]。
对于第二组,要判断加上这部分长度会不会超过k,ans的增量在dp里找就可以了。
时间复杂度O(nk)。
/**************************************************** >Created Date: 2015-10-01-13.34.56 >My Soul, Your Beats! ****************************************************/ #include <bits/stdc++.h> using namespace std; typedef long long LL; const int INF = 1 << 30; const long long LINF = 1LL << 50; const int M = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-6; int seq[M], seq2[M]; LL dp[2][M]; const int MOD = 1e9 + 7; int main(){ #ifndef ONLINE_JUDGE // freopen("in.in", "r", stdin); #endif // ONLINE_JUDGE LL n, l, k; scanf("%I64d %I64d %I64d", &n, &l, &k); for(int i = 0; i < n; i++) { scanf("%d", &seq[i]); seq2[i] = seq[i]; } sort(seq2, seq2 + n); for(int i = 0; i < n; i++) seq[i] = lower_bound(seq2, seq2 + n, seq[i]) - seq2; int maxn = 0; for(int i = 0; i < n; i++) maxn = max(maxn, seq[i]); maxn++; LL c = l / n, d = l % n; for(int i = 0; i < d; i++) seq2[i] = seq[i]; LL ans = 0; int id = 0; for(int i = 0; i < min(c, k); i++){ id ^= 1; for(int j = 0; j <= maxn; j++) dp[id][j] = 0; for(int j = 0; j < n; j++) dp[id][seq[j]] = (dp[id][seq[j]] + dp[id ^ 1][seq[j]] + 1) % MOD; for(int j = 1; j < maxn; j++) dp[id][j] = (dp[id][j] + dp[id][j - 1]) % MOD; ans = (ans + dp[id][maxn - 1]) % MOD; } if(c > k) ans = (ans + dp[id][maxn - 1] * ((c - k) % MOD)) % MOD; int t = id; if(c >= k) t ^= 1; for(int i = 0; i < d; i++){ ans += dp[t][seq2[i]] + 1; ans %= MOD; } cout << ans << endl; return 0; }
相关文章推荐
- 如何绑定PasswordBox控制中的Password属性
- PHP 7的一些引人注目的新特性简单介绍
- Springloaded使用
- Android基础入门教程——9.2 MediaPlayer播放音频与视频
- select into from 和 insert into select 的用法和区别
- 01分数规划
- JAVA的内省机制(introspector)与反射机制(reflection)
- 汇编语言-内中断
- [Machine Learning]4.逻辑回归(logistic regression)
- 学习SASS
- Mybatis 源码分析--crud
- 汇编语言-内中断
- 使用shell脚本搭建源码LAMP环境
- 复习线段树
- Mac上远程桌面连接Windows Server 2012 R2
- opencv中结构体分析
- 星空
- Linux忘记 root密码的解决办法
- mysql之lvm快照方式备份恢复
- mysql备份还原数据库