BZOJ2038 小z的袜子

今天新学习了莫队算法,感觉好神,离线的询问好像都可以用莫队。

要不是坑爹的HNOI2016考了两道莫队题,才不得不来入这个坑

 

题目大意就是给一些数,然后每次询问一段区间,问从这个区间中抽走两个数,抽到相同的数的概率

 

把询问离线下来,然后按照左端点所在块的编号来排序,若在同一个块则以右端点编号排序(有点像分块)

然后我每次暴力处理一下一个询问,之后利用这一次的结果,往前或者往后拓展,把处在同一个快的全部都可以处理掉(期望复杂度:O(1))

最终可以达到O(N^1.5)的复杂度

复杂度证明的话,感觉yy一下可以想得到

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 using namespace std;
10 typedef long long LL;
11 const int MAXN = 50011;
12 const int MAXM = 50011;
13 int n,m;
14 int color[MAXN];
15 LL ans[MAXM];
16 int siz,zong;
17 LL size[MAXN];
18 LL num[MAXN];
19 //莫队算法
20
21 struct wen{
22     int l,r;
23     int jilu;
24     int k;//存储所在块的编号
25 }Q[MAXM];
26
27 inline int getint()
28 {
29        int w=0,q=0;
30        char c=getchar();
31        while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar();
32        if (c==‘-‘)  q=1, c=getchar();
33        while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar();
34        return q ? -w : w;
35 }
36
37 bool cmp(wen q,wen qq){ if(q.k==qq.k) return q.r<qq.r; return q.k<qq.k;  }
38 //按照左端点所在块的编号来排序,若相等则以右端点编号为序
39
40 inline LL gcd(LL x,LL y) { return y==0? x:gcd(y,x%y); }
41
42 int main()
43 {
44     freopen("hose.in","r",stdin);
45     freopen("hose.out","w",stdout);
46     n=getint();m=getint();
47     for(int i=1;i<=n;i++) color[i]=getint();
48
49     zong=sqrt(n); if(zong*zong==n) siz=zong; else siz=n/zong+1;
50
51     for(int i=1;i<=m;i++) {
52     Q[i].l=getint(),Q[i].r=getint(),Q[i].jilu=i,size[i]=Q[i].r-Q[i].l+1;
53     Q[i].k=(Q[i].l-1)/siz+1;
54     }
55
56     sort(Q+1,Q+m+1,cmp);
57     int ljh=1;
58     while(ljh<=m) {
59     int kuai=Q[ljh].k;
60
61     memset(num,0,sizeof(num));
62
63     for(int j=Q[ljh].l;j<=Q[ljh].r;j++) ans[Q[ljh].jilu]+=2*(num[color[j]]++);
64     ljh++;
65
66     for(;Q[ljh].k==kuai;ljh++) {
67         ans[Q[ljh].jilu]=ans[Q[ljh-1].jilu];
68         for(int j=Q[ljh-1].r+1 ;j<=Q[ljh].r;j++) ans[Q[ljh].jilu]+=2*(num[color[j]]++);
69
70         if(Q[ljh].l>Q[ljh-1].l) for(int j=Q[ljh-1].l;j<Q[ljh].l;j++) ans[Q[ljh].jilu]-=2*(--num[color[j]]);
71         else for(int j=Q[ljh].l;j<Q[ljh-1].l;j++) ans[Q[ljh].jilu]+=2*(num[color[j]]++);
72     }
73     }
74
75     for(int i=1;i<=m;i++) {
76     LL fenmu;
77     if(size[i]==1) fenmu=1;
78     else fenmu=size[i]*(size[i]-1);
79     LL gong=gcd(fenmu,ans[i]);
80     printf("%lld/%lld\n",ans[i]/gong,fenmu/gong);
81     }
82
83     return 0;
84 }
时间: 2024-10-23 02:43:13

BZOJ2038 小z的袜子的相关文章

bzoj2038 小z的袜子 (莫队)

题目大意 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务便是告诉小Z,他有多大的概率抽到两只颜色相同的袜子.当然,小Z希望这个概率尽量高,所以他可能会询问多个(L,R)以方便自己选择. 100

bzoj2038小z的袜子

用平面曼哈顿距离最小生成树或者莫队算法都可以吖QwQ~ 然而显然后者更好写(逃~) 莫队怎么写就看图吧QwQ~ 话说我一开始没开long long然后拍了3000组没拍出错交上去Wa了QAQ #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #define int long long using namespace s

bzoj-2038 小Z的袜子 hose

题意: 给出一个长度为n的序列,每次询问一个区间[l,r]: 查询在这个区间中取出两个数恰好相等的概率: 每个数大小在[0,n]内,概率用既约分数表示: 题解: 考虑一个区间的答案,显然是合法方案数/取数的所有可能: 也就是 ∑C[同种数字个数][2]/C[r-l+1][2]: 但是这个东西对一次询问的处理复杂度是O(r-l+1)的: 那么考虑上莫队算法,处理这样的区间问题: 很容易发现每次修改边界可以做到O(1)完成: void update(int x,int op) { now-=C[s[

bzoj2038 小Z的袜子(hose)——莫队算法

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 就是莫队算法: 先写了个分块,惨WA: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; int const maxn=

bzoj 2038 小Z的袜子(hose)(莫队算法)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 11542  Solved: 5166[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命--具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只

清橙A1206 小Z的袜子(莫队算法)

A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB 总提交次数:744   AC次数:210   平均分:44.44 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2010中国国家集训队命题答辩 问题描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是

【BZOJ】2038: [2009国家集训队]小Z的袜子(hose)

[算法]莫队 [题解] BZOJ 2038 2009国家集训队 小Z的袜子(hose) 莫队算法 莫队--讲稿? 施工中--

BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )

莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) ------------------------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 50009; int N,