Atcoder arc077 D - 11 组合
题意:给出n个数,其中有一个数会出现两次,其余数只出现一次,问不同长度且不同的子串的数量。取模1e9+7
思路:组合求出所有情况,减去重复情况,注意用逆元即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /** @Date : 2017-07-06 09:56:44 * @FileName: atcoder077 D 组合.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; const LL mod = 1e9 + 7; LL a[N]; LL inv[N]; LL fa[N]; LL n; void init() { fa[0] = fa[1] = 1; inv[1] = 1; for (LL i = 2; i < N; i++) { fa[i] = fa[i-1] * i % mod; inv[i] = (mod - mod / i) * inv[mod % i] % mod; } inv[0] = 1; for ( int i = 1; i < N; i++) (inv[i] *= inv[i - 1]) %= mod; } LL C(LL n, LL k) { LL ans = 0; if (k > n) return ans; ans = ((fa[n] * inv[k] % mod) * inv[n - k]) % mod; return ans; } int main() { init(); while (cin >> n) { map<LL, int >q; LL p = 0; for ( int i = 1; i <= n + 1; i++) { scanf ( "%lld" , a + i); if (!q[a[i]]) q[a[i]] = i; else p = i; } for ( int i = 0; i <= n; i++) { LL ans = 0; ans = (ans + C(n + 1, i + 1)) % mod; ans = (ans - C(n - p + q[a[p]], i)) % mod; while (ans < 0) ans += mod; printf ( "%lld\n" , ans); } } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步