BZOJ 2038: 小Z的袜子
来源:互联网 发布:网络硬盘 免费 编辑:程序博客网 时间:2024/05/19 23:01
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2038
题目大意
给定一个序列。
每次询问一个区间,求在这个区间中选取两个数,两数相同的概率有多大。
算法:
这道题是莫队算法模板题。
莫队算法是一种解决区间询问类问题的通用算法,效率是O(n * sqrt(n)) 乘以每次询问的复杂度。
莫队算法有两种实现方法,一种是欧几里得最小生成树,一种是分块算法。
我采用的是分块算法,编码复杂度比较低。
先把询问按 sqrt(l)排序、分成sqrt(n)个块,然后每块中按照r排序
最后每次从前一个询问修改得到下一个询问的值。
总的时间复杂度是O(n * sqrt(n)) 乘以每次询问的复杂度,在此不再证明。
代码如下:
#include <cstdio>#include <iostream>#include <algorithm>#include <sstream>#include <cstdlib>#include <cstring>#include <string>#include <climits>#include <cmath>#include <queue>#include <vector>#include <stack>#include <set>#include <map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;typedef long long LL;#define mp make_pair#define fi first#define nd secondtypedef pair <int, int> PII;typedef pair <PII, int> PIII;const int maxn = 51000, maxm = 51000;PIII a[maxm];long long ans1[maxm], ans2[maxm], cot[maxn];int c[maxn];int n, m;LL gcd(LL a, LL b){ return b ? gcd(b, a % b) : a;}void update(int pos, int x, int flg){ ans1[pos] -= cot[c[x]] * cot[c[x]]; cot[c[x]] += flg; ans1[pos] += cot[c[x]] * cot[c[x]];}bool cmp(const PIII &a, const PIII &b){ int posa = a.fi.fi/(int)sqrt(n); int posb = b.fi.fi/(int)sqrt(n); if(posa == posb) { return a.fi.nd < b.fi.nd; } return posa < posb;}int main(){ while(scanf("%d %d", &n, &m) == 2) { memset(cot, 0, sizeof(cot)); for(int i = 1; i <= n; i ++) { scanf("%d", &c[i]); } for(int i = 0; i < m; i ++) { int l, r; scanf("%d %d", &l, &r); a[i] = mp(mp(l, r), i); ans2[i] = r - l + 1; } sort(a, a + m, cmp); for(int i = 0, l = 1, r = 0; i < m; i ++) { if(i) { ans1[a[i].nd] = ans1[a[i - 1].nd]; } else { ans1[i] = 0; } while(l > a[i].fi.fi) { l --; update(a[i].nd, l, 1); } while(l < a[i].fi.fi) { update(a[i].nd, l, -1); l ++; } while(r > a[i].fi.nd) { update(a[i].nd, r, -1); r --; } while(r < a[i].fi.nd) { r ++; update(a[i].nd, r, 1); } } for(int i = 0; i < m; i ++) { ans1[i] -= ans2[i]; ans2[i] *= ans2[i] - 1; if(ans1[i]) { long long k = gcd(ans1[i], ans2[i]); ans1[i] /= k; ans2[i] /= k; } else { ans2[i] = 1; } printf("%lld/%lld\n",ans1[i], ans2[i]); } } return 0;}
- BZOJ 2038: 小Z的袜子
- BZOJ 2038小Z的袜子 分块
- BZOJ 2038 小z的袜子
- bzoj-2038 小Z的袜子 hose
- BZOJ 2038 小Z的袜子(hose)
- BZOJ 2038 小Z的袜子
- 【BZOJ】2038 小Z的袜子
- BZOJ 2038 小Z的袜子
- 【BZOJ 2038】小Z的袜子
- BZOJ 2038 小Z的袜子
- BZOJ 2038小z的袜子
- bzoj 2038 小Z的袜子
- bzoj 2038 小Z的袜子 莫队
- bzoj 2038 小z的袜子 莫队
- bzoj 2038 小z的袜子
- bzoj 2038: [2009国家集训队]小Z的袜子(hose)
- 【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose)
- 线性莫队算法 BZOJ 2038 小Z的袜子
- Java 数据库操作
- 接口开发注意事项
- MongoDB MapReduce速度提升20倍的优化宝典
- 讲述下HTML5所包含的特殊符号的意思
- POJ3468 顺便贴个学姐的线段树版
- BZOJ 2038: 小Z的袜子
- 解决不同编码,不同语言间传递数据乱码的通用办法
- 5、ip选路
- NYOJ187快速判断素数
- 在CentOS下安装配置MySQL
- COM组件
- OPENGL中GLU和GLUT工具箱
- Oracle内连接、外连接、右外连接、全外连接小总结
- Web 开发与设计之 Google 兵器谱