bzoj 2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=2038
【题意】
给定一个有颜色的序列,回答若干个询问:区间内任选两个颜色相同的概率。
【思路】
设一个颜色在区间内的出现次数为cnt,则抽到这种颜色的概率为:
(cnt-1)*cnt/2 = 1+2+…+cnt-1
对于一个区间我们就可以使用一个cnt数组通过扫一遍得出答案。暴力的话,可以拿两个指针,每次移动指针,对数据进行插入与删除。
莫队算法就是在此基础上有序化了数据。将序列每sqrt(n)分成一块,根据查询的左端点所在块编号和右端点为第一二关键字排序。相邻的区间的重叠部分不重复计算,而是采用移动指针的方法,并通过合适的数据结构维护区间内的数据,支持在原来答案的基础上添加或删除数据即区间移动。
关于复杂度的分析:
一、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部分时间复杂度是n^1.5。
二、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
三、i与i+1在同一块内时变化不超过n^0.5,跨越一块也不会超过2*n^0.5,不妨看作是n^0.5。由于有n个数,所以时间复杂度是n^1.5
于是就变成了O(n^1.5)了from...不详
【代码】
1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 11 using namespace std; 12 13 typedef long long ll; 14 const int N = 5e4+10; 15 16 ll read() { 17 char c=getchar(); 18 ll f=1,x=0; 19 while(!isdigit(c)) { 20 if(c=='-') f=-1; c=getchar(); 21 } 22 while(isdigit(c)) 23 x=x*10+c-'0',c=getchar(); 24 return x*f; 25 } 26 27 struct Node 28 { 29 int pos,l,r,id; 30 bool operator < (const Node& rhs) const 31 { 32 return pos<rhs.pos||(pos==rhs.pos&&r<rhs.r); 33 } 34 }q[N]; 35 36 ll gcd(ll a,ll b) 37 { 38 return b==0? a:gcd(b,a%b); 39 } 40 41 int n,m,c[N],cnt[N]; 42 pair<int,int> ans[N]; 43 44 int main() 45 { 46 n=read(),m=read(); 47 FOR(i,1,n) c[i]=read(); 48 int B=sqrt(n); 49 FOR(i,1,m) 50 { 51 q[i].l=read(); 52 q[i].r=read(); 53 q[i].pos=(q[i].l-1)/B+1; 54 q[i].id=i; 55 } 56 sort(q+1,q+m+1); 57 int l=1,r=0; ll now=0; 58 FOR(i,1,m) 59 { 60 while(l>q[i].l) 61 now+=cnt[c[--l]]++; 62 while(l<q[i].l) 63 now-=--cnt[c[l++]]; 64 while(r<q[i].r) 65 now+=cnt[c[++r]]++; 66 while(r>q[i].r) 67 now-=--cnt[c[r--]]; 68 ll sum=(ll)(r-l+1)*(r-l)/2; 69 ll g=gcd(sum,now); 70 ans[q[i].id]=make_pair((int)now/g,(int)sum/g); 71 } 72 FOR(i,1,m) 73 printf("%d/%d\n",ans[i].first,ans[i].second); 74 return 0; 75 }
posted on 2016-04-01 09:07 hahalidaxin 阅读(300) 评论(1) 编辑 收藏 举报