HDU - 5145 莫队算法
2017-04-10 19:44
417 查看
题意:
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5145有n个女生,每个女生都属于一个教室,现在要访问这些女生,就要进入教室,每次进入一个教室只能访问该教室的一个女生,现在要问对于[L,R]之间的女生全部访问,一共有多少种不同的访问教室的方式?
思路:
仔细想一下,因为最后的方案按照教室的不同来划分,那就与教室内部的女生访问顺序没有关系,那么只要拿所有女生的访问的排列数除以每个教室女生的排列数即可。区间查询问题,不涉及修改操作,而且区间改变一个单位的大小只需要O(1)的时间,典型的莫队算法可以处理的类型。
分块加速,以及要求逆元。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 1e9 + 7; const int MAXN = 3e4 + 10; LL inv[MAXN]; void init() { inv[0] = inv[1] = 1; for (int i = 2; i <= 30000; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD; } LL cur, num; int cnt[MAXN], a[MAXN], p[MAXN]; void add(int pos) { ++num; ++cnt[a[pos]]; cur = cur * num % MOD; cur = cur * inv[cnt[a[pos]]] % MOD; } void del(int pos) { cur = cur * inv[num] % MOD; cur = cur * cnt[a[pos]] % MOD; cnt[a[pos]]--; num--; } struct Query { int l, r, id; bool operator < (const Query &rhs) const { return p[l] == p[rhs.l] ? r < rhs.r : p[l] < p[rhs.l]; } } q[MAXN]; LL ans[MAXN]; int main() { //freopen("in.txt", "r", stdin); init(); int T; scanf("%d", &T); while (T--) { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int block = ceil(sqrt(n)); for (int i = 1; i <= n; i++) p[i] = (i - 1) / block; for (int i = 1; i <= m; i++) { scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } sort(q + 1, q + 1 + m); memset(cnt, 0, sizeof(cnt)); cur = 0, num = 0; add(1); cur = 1; int l = 1, r = 1; for (int i = 1; i <= m; i++) { while (r > q[i].r) { del(r); r--; } while (r < q[i].r) { ++r; add(r); } while (l > q[i].l) { --l; add(l); } while (l < q[i].l) { del(l); l++; } ans[q[i].id] = cur; } for (int i = 1; i <= m; i++) printf("%I64d\n", ans[i]); } return 0; }
相关文章推荐
- ACM 算法总结 --- 排序 HDOJ HDU 2094 产生冠军 ACM 2094 IN HDU
- hdu Gauss Fibonacci
- hdu1.1.2
- hdu 1878欧拉回路
- hdu 3519 Lucky Coins Sequence
- HDU 2883 kebab (最大流)
- hdu 4240 Route Redundancy(最大流)
- hdu 1069 mokey and banana
- hdu_2925_Musical Chairs_201311121643
- HDU 1535
- hdu 1142 记忆化搜索
- hdu 1001
- 【瞎搞】HDU 3257 Hello World!
- HDU 2030 统计汉字
- hdu 1016 Prime Ring Problem
- N次剩余 (hdu 3930)
- HDU 2094产生冠军(拓扑排序)
- HDU 1671 Phone List (Trie)
- HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
- HDU 4587 TWO NODES(割点,连通块,枚举)