P1494 [国家集训队]小Z的袜子
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1494 [国家集训队]小Z的袜子相关的知识,希望对你有一定的参考价值。
偷偷地切莫队模板题。。。
讲道理这道题也是很普通的莫队模板题。
让你求了个概率,其实就是问你(sum{frac{cnt[i] imes (cnt[i]-1)}{2}})。分母是人都能求吧。求出两个东西之后约分即可。
分子这个东西,其实就是一道同样的莫队题“小B的询问”中的维护方法。
每多一个数,答案就不一样。那么我们减掉当前的对答案的贡献, 更新cnt数组,再加上新的对答案的贡献,就可以维护了。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#define LL long long
const int maxn = 50005;
struct Query
{
LL l, r, id;
} ques[maxn];
LL belong[maxn];
LL out1[maxn], out2[maxn];
LL cnt[maxn];
LL a[maxn];
LL n, m;
LL l = 1, r = 0, ans = 0;
bool cmp(Query a, Query b)
{
if(belong[a.l] == belong[b.l]) return a.r < b.r;
return belong[a.l] < belong[b.l];
}
LL read()
{
LL ans = 0, s = 1;
char ch = getchar();
while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); }
while(ch >= ‘0‘ && ch <= ‘9‘) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar();
return s * ans;
}
void add(LL x)
{
ans -= (cnt[x] * (cnt[x] - 1)) / 2;
cnt[x]++;
ans += (cnt[x] * (cnt[x] - 1)) / 2;
}
void del(LL x)
{
ans -= (cnt[x] * (cnt[x] - 1)) / 2;
cnt[x]--;
ans += (cnt[x] * (cnt[x] - 1)) / 2;
}
void moqueue()
{
LL block = sqrt(n);
for(int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1;
std::sort(ques + 1, ques + m + 1, cmp);
for(int i = 1; i <= m; i++)
{
if(ques[i].l == ques[i].r)
{
out1[ques[i].id] = 0, out2[ques[i].id] = 1;
continue;
}
while(l < ques[i].l) del(a[l++]);
while(l > ques[i].l) add(a[--l]);
while(r > ques[i].r) del(a[r--]);
while(r < ques[i].r) add(a[++r]);
out1[ques[i].id] = ans;
out2[ques[i].id] = (r - l + 1) * (r - l) / 2;
}
}
LL gcd(LL x, LL y)
{
return y == 0 ? x : gcd(y, x % y);
}
int main()
{
n = read(), m = read();
for(int i = 1; i <= n; i++) a[i] = read();
for(int i = 1; i <= m; i++) ques[i].l = read(), ques[i].r = read(), ques[i].id = i;
moqueue();
for(int i = 1; i <= m; i++)
{
LL ans1 = out1[i], ans2 = out2[i];
LL g = gcd(ans1, ans2);
ans1 /= g; ans2 /= g;
printf("%lld/%lld
", ans1, ans2);
}
return 0;
}
以上是关于P1494 [国家集训队]小Z的袜子的主要内容,如果未能解决你的问题,请参考以下文章