【BZOJ 2038】小Z的袜子 (莫队算法)
来源:互联网 发布:专业生物英语软件 编辑:程序博客网 时间:2024/06/11 17:54
传送门
BZOJ 2038 小Z的袜子
I think
题意:给出长度为n的区间与若干形如[l,r]的区间,询问在[l,r]内两个不同位置取到两个相同的数的概率。
算法:莫队
思想:将组合数求概率的式子化简一下:
(col 表示区间内颜色总数 f[i]表示区间内颜色出现次数)
于是我们可以看伟大的黄学长题解
莫队算法
如果我们已知[l,r]的答案,能在O(1)时间得到[l+1,r]的答案以及[l,r-1]的答案,即可使用莫队算法。时间复杂度为O(n^1.5)。如果只能在logn的时间移动区间,则时间复杂度是O(n^1.5*log n)。
其实就是找一个数据结构支持插入、删除时维护当前答案。
这道题的话我们很容易用数组来实现,做到O(1)的从[l,r]转移到[l,r+1]与[l+1,r]。
那么莫队算法怎么做呢?以下都是在转移为O(1)的基础下讨论的时间复杂度。另外由于n与m同阶,就统一写n。
如果已知[l,r]的答案,要求[l’,r’]的答案,我们很容易通过|l – l’|+|r – r’|次转移内求得。
将n个数分成sqrt(n)块。
按区间排序,以左端点所在块内为第一关键字,右端点为第二关键字,进行排序,也就是以(pos [l],r)排序
然后按这个排序直接暴力,复杂度分析是这样的:
1、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部分时间复杂度是n^1.5。
2、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
3、i与i+1在同一块内时l变化不超过n^0.5,跨越一块也不会超过n^0.5,忽略*2。由于有m次询问(和n同级),所以时间复杂度是n^1.5
于是就是O(n^1.5)了
最后最小公倍数约一下分子分母就可以输出答案了。
Code
#include<cmath>#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int sm = 50000+10;LL Ans;int N,M,Blk;int S[sm],C[sm],pos[sm];struct Que { int id,l,r; LL a,b;}A[sm];LL Gcd(LL a,LL b) { return b == 0?a:Gcd(b,a%b); } LL ind(int x) { return 1ll*x*x; }void read(int &x) { char ch=getchar();x=0; while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();}void Out(LL a) { if(a>9) Out(a/10); putchar('0'+a%10);}bool cmpa(Que x,Que y) { return (pos[x.l]!=pos[y.l])?pos[x.l]<pos[y.l]:x.r<y.r;}bool cmpb(Que x,Que y) { return x.id<y.id; }void Update(int p,int add) { Ans-=ind(S[C[p]]); S[C[p]]+=add; Ans+=ind(S[C[p]]);}void Solve() { int l=1,r=0;//注意l=1的细节 LL k; for(int i=1;i<=M;++i) { for(;r<A[i].r;++r) Update(r+1,1); for(;r>A[i].r;--r) Update(r,-1); for(;l<A[i].l;++l) Update(l,-1); for(;l>A[i].l;--l) Update(l-1,1); if(A[i].l==A[i].r) { A[i].a=0,A[i].b=1; continue; } A[i].a=Ans-(A[i].r-A[i].l+1); A[i].b=1ll*(A[i].r-A[i].l+1)*(A[i].r-A[i].l); k=Gcd(A[i].a,A[i].b); A[i].a/=k,A[i].b/=k; }}int main() { read(N),read(M); Blk=sqrt(N); for(int i=1;i<=N;++i) read(C[i]),pos[i]=(i-1)/Blk+1; for(int i=1;i<=M;++i) read(A[i].l),read(A[i].r),A[i].id=i; sort(A+1,A+M+1,cmpa); Solve(); sort(A+1,A+M+1,cmpb); for(int i=1;i<=M;++i) { Out(A[i].a),putchar('/'); Out(A[i].b),putchar(10); } return 0;}
- 线性莫队算法 BZOJ 2038 小Z的袜子
- 小Z的袜子(hose) - bzoj 2038 莫队算法
- BZOJ 2038 小Z的袜子(莫队算法)
- BZOJ 2038 小Z的袜子 莫队算法介绍
- BZOJ 2038 小Z的袜子(hose) 莫队算法
- bzoj 2038 小Z的袜子 [莫队算法] [概率]
- BZOJ-2038 小Z的袜子(hose) (莫队算法)
- [BZOJ]2038 小Z的袜子 莫队算法
- 【BZOJ 2038】小Z的袜子&莫队算法详解
- BZOJ 2038 小Z的袜子(hose) [莫队算法]
- 莫队算法(小Z的袜子,BZOJ 2038)
- BZOJ 2038 小Z的袜子 莫队算法入门
- BZOJ 2038 小Z的袜子 (莫队算法)
- 【BZOJ 2038】小Z的袜子 (莫队算法)
- 莫队算法 BZOJ 2038 小Z的袜子
- 【BZOJ】【P2038】【小Z的袜子】【题解】【莫队算法】
- bzoj 2038 小Z的袜子 莫队模板
- 莫队总结&bzoj 2038 小Z的袜子
- *p和**p的区别
- 程序直接运行和用gdb单步执行结果不同
- 贝叶斯实战
- Adaboost 详解
- 迭代器模式
- 【BZOJ 2038】小Z的袜子 (莫队算法)
- 在Nuget管理器上安装MvvmLight框架,有时候会有如下提示: “MvvmLightLibs”已拥有为“CommonServiceLocator”定义的依赖项。
- Python-OpenCV图像阈值
- 异或
- 单通道子空间降噪法
- codeforces 808D Array Division(二分+思维)
- 暑假集训日记--8.17--树状数组+练习赛
- 2017 集训后计划
- 动态测试