Pixiv - Miracle
4-P1494 [国家集训队] 小 Z 的袜子
782 字
4 分钟
4-P1494 [国家集训队] 小 Z 的袜子
P1494 [国家集训队] 小 Z 的袜子
题目描述
upd on 2020.6.10 :更新了时限。
作为一个生活散漫的人,小 Z 每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小 Z 再也无法忍受这恼人的找袜子过程,于是他决定听天由命……
具体来说,小 Z 把这 只袜子从 到 编号,然后从编号 到 的袜子中随机选出两只来穿。尽管小 Z 并不在意两只袜子是不是完整的一双,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬。
你的任务便是告诉小 Z,他有多大的概率抽到两只颜色相同的袜子。当然,小 Z 希望这个概率尽量高,所以他可能会询问多个 以方便自己选择。
然而数据中有 的情况,请特判这种情况,输出
0/1。输入格式
输入文件第一行包含两个正整数 和 。 为袜子的数量, 为小 Z 所提的询问的数量。接下来一行包含 个正整数 ,其中 表示第 只袜子的颜色,相同的颜色用相同的数字表示。再接下来 行,每行两个正整数 表示一个询问。
输出格式
包含 行,对于每个询问在一行中输出分数 表示从该询问的区间 中随机抽出两只袜子颜色相同的概率。若该概率为 则输出
0/1,否则输出的 必须为最简分数。(详见样例)输入输出样例 #1
输入 #1
6 41 2 3 3 3 22 61 33 51 6输出 #1
2/50/11/14/15说明/提示
的数据中,;
的数据中,;
的数据中,,,。
莫队模板
#include <bits/stdc++.h>
using namespace std;using ll = long long;
const int N = 50000 + 1;
int n, m;int col[N];int block;int cnt[N];ll ans1[N], ans2[N];ll sum;
struct query { ll l, r, id;
bool operator<(const query& q) const { int bl = l / block; int br = q.l / block; if (bl != br) return bl < br; if (bl & 1) return r < q.r; return r > q.r; }
} a[N];
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a;}
void add(int x) { sum += cnt[col[x]]; ++cnt[col[x]];}
void del(int x) { sum -= (cnt[col[x]] - 1); --cnt[col[x]];}
void solve() { cin >> n >> m; if (m == 0) return;
block = int(n / sqrt(m)) + 1;
for (int i = 1; i <= n; ++i) cin >> col[i];
for (int i = 0; i < m; ++i) { cin >> a[i].l >> a[i].r; a[i].id = i; } sort(a, a + m);
for (ll i = 0, l = 1, r = 0; i < m; ++i) { query& q = a[i]; while (l > q.l) add(--l); while (r < q.r) add(++r); while (l < q.l) del(l++); while (r > q.r) del(r--); ans1[q.id] = sum; ans2[q.id] = (r - l + 1) * (r - l) / 2; }
for (int i = 0; i < m; ++i) { if (ans1[i] && ans2[i]) { ll d = gcd(ans1[i], ans2[i]); cout << ans1[i] / d << '/' << ans2[i] / d << '\n'; } else { cout << 0 << '/' << 1 << '\n'; } }}
int main() { cin.tie(nullptr)->sync_with_stdio(false); solve();}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
4-P1494 [国家集训队] 小 Z 的袜子
https://skaco2.com/posts/03-solutions/4-p1494-国家集训队-小-z-的袜子/ 随机文章 随机推荐