【bzoj 2038】 [2009国家集训队]小Z的袜子(算法效率--莫队分块算法 模版题)
题意:小Z有N只袜子,有不同的颜色。他有M个提问,问从编号为[L,R]的袜子中随机选一双同色的袜子的概率,用最简分数表示。
解法:经典的莫队算法——无修改、不强制在线(可离线)、状态转移可以一步完成。
步骤如下:
1.对询问按第一关键字的平方根 sqrt(x) 从小到大排序进行分组,再是各组中按第二关键字 y 从小到大排序。O(m log m)。
2.一步步转移,第一关键字最多转移 O(sqrt(n)),第二关键字是 O(n) ,相结合就是 O(n*sqrt(n))。
总时间复杂度就是 O(n*sqrt(n))。
P.S.我第一个代码WA怎么改都对不了,应该是不能直接对颜色的计数数组通过 +1 和 -1 对答案的贡献不同而直接转移状态。而要减去原来该数对答案的贡献,再加上新的贡献。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5 #include<iostream>
6 #include<cmath>
7 using namespace std;
8 typedef long long LL;
9
10 const int N=50010,M=50010,D=50010;
11 int n,m,sqn;
12 int c[N],h[N];
13 LL ans[M][2];
14 struct query{int l,r,id;}q[M];
15
16 bool cmp(query x,query y)
17 {
18 int xx=x.l/sqn,yy=y.l/sqn;
19 if (xx!=yy) return xx<yy;
20 return x.r<y.r;
21 }
22 int read()
23 {
24 char ch=getchar();
25 int x=0;
26 while (ch<'0'||ch>'9') ch=getchar();
27 while (ch>='0'&&ch<='9') x=x*10+ch-'0', ch=getchar();
28 return x;
29 }
30 LL gcd(int x,int y) {return y?gcd(y,x%y):x;}
31 int main()
32 {
33 n=read(),m=read();
34 for (int i=1;i<=n;i++) c[i]=read();
35 for (int i=1;i<=m;i++)
36 {
37 q[i].l=read(),q[i].r=read();
38 q[i].id=i;
39 }
40 sqn=sqrt(n);
41 sort(q+1,q+1+m,cmp);
42
43 int l=1,r=1;
44 LL sum=0;
45 memset(h,0,sizeof(h));
46 h[c[1]]++;
47 for (int i=1;i<=m;i++)
48 {
49 while (l<q[i].l) sum=sum-2*h[c[l]]+2,h[c[l]]--,l++;
50 while (r>q[i].r) sum=sum-2*h[c[r]]+2,h[c[r]]--,r--;
51 while (l>q[i].l) l--,sum+=2*h[c[l]],h[c[l]]++;
52 while (r<q[i].r) r++,sum+=2*h[c[r]],h[c[r]]++;
53 LL w=(q[i].r-q[i].l)*(q[i].r-q[i].l+1);
54 LL gd=gcd(sum,w);
55 ans[q[i].id][0]=sum/gd,ans[q[i].id][1]=w/gd;
56 }
57 for (int i=1;i<=m;i++)
58 printf("%I64d/%I64d\n",ans[i][0],ans[i][1]);
59 return 0;
60 }
WA
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cmath>
4 #include<cstring>
5 #include<iostream>
6 using namespace std;
7 const int Max=50010;
8 int n,m,t=0;
9 int s[Max],c[Max],ans1[Max],ans2[Max];
10 struct hp{int l,r,t,k;}
11 a[Max];
12 int gcd(int x,int y)
13 {
14 if (x<y) swap(x,y);
15 if (x%y==0) return y;
16 return gcd(y,x%y);
17 }
18 int cmp(const void *x,const void *y)
19 {
20 hp xx=*(hp *)x;
21 hp yy=*(hp *)y;
22 if (xx.t==yy.t) return xx.r-yy.r;
23 return xx.t-yy.t;
24 }
25 int make(int x)
26 { //if (x<2) return 0;
27 if (x%2==0) return (x/2)*(x-1);
28 return x*((x-1)/2);
29 }
30 void block(int id,int l,int r,int ll,int rr)
31 {
32 /*if (ll<l)
33 for (int i=ll;i<l;i++)
34 {//因为ll为0,所以每次都会make(-1),出现负数便错误!//若特殊算第一次,或算1~n为初始值,才行
35 //幸亏我想着算组合make时,若x<2宣布了2个怎么办,没有进一步看x=0或1时不会算错,就加了判断语句,便发现对了一些
36 t-=make(s[c[i]]);
37 s[c[i]]--;
38 t+=make(s[c[i]]);
39 }*/
40 if (ll<l)
41 for (int i=ll;i<l;i++)
42 {
43 t-=make(s[c[i]]);
44 s[c[i]]--;
45 t+=make(s[c[i]]);
46 }
47 if (ll>l)
48 for (int i=l;i<ll;i++)
49 {
50 t-=make(s[c[i]]);
51 s[c[i]]++;
52 t+=make(s[c[i]]);
53 }
54 if (rr<r)
55 for (int i=rr+1;i<=r;i++)
56 {
57 t-=make(s[c[i]]);
58 s[c[i]]++;
59 t+=make(s[c[i]]);
60 }
61 if (rr>r)
62 for (int i=r+1;i<=rr;i++)
63 {
64 t-=make(s[c[i]]);
65 s[c[i]]--;
66 t+=make(s[c[i]]);
67 }
68 int tt,x;
69 if (!t) {ans1[a[id].k]=0; ans2[a[id].k]=1; return;}
70 tt=make(r-l+1);//t/tt
71 x=gcd(tt,t);
72 ans1[a[id].k]=t/x;
73 ans2[a[id].k]=tt/x;
74 }
75 int main()
76 {
77 //freopen("a.in","r",stdin);
78 //freopen("b.out","w",stdout);
79 scanf("%d%d",&n,&m);
80
81 for (int i=1;i<=n;i++)
82 scanf("%d",&c[i]);
83 double x=sqrt(n);
84 for (int i=1;i<=m;i++)
85 {
86 scanf("%d%d",&a[i].l,&a[i].r);
87 a[i].t=(int)(a[i].l/x);
88 a[i].k=i;
89 }
90 qsort(a+1,m,sizeof(hp),cmp);
91
92 memset(s,0,sizeof(s));
93 //a[0].l=0; a[0].r=0;
94 a[0].l=1;a[0].r=n;
95 for (int i=1;i<=n;i++) s[c[i]]++;
96 for (int i=1;i<=n;i++)
97 t+=make(s[i]);
98 for (int i=1;i<=m;i++)
99 block(i,a[i].l,a[i].r,a[i-1].l,a[i-1].r);
100 for (int i=1;i<=m;i++)
101 printf("%d/%d\n",ans1[i],ans2[i]);
102 //system("pause");
103 return 0;
104 }
AC
【bzoj 2038】 [2009国家集训队]小Z的袜子(算法效率--莫队分块算法 模版题)的更多相关文章
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题&&学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 9894 Solved: 4561[Subm ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法】
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- bzoj 2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2038 [题意] 给定一个有颜色的序列,回答若干个询问:区间内任选两个颜色相同的概率. ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法模版】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 题意概括: 有 N 只袜子(分别编号为1~N),有 M 次查询 (L, R)里面随机 ...
- BZOJ 2038 2009国家集训队 小Z的袜子【模板·莫队】
[题解] 1,先说说莫队算法. 莫队算法是用来离线处理区间问题的算法.非常易于理解和使用,且运用十分广泛. 假设我们现在已知区间[L,R]的答案,如果我们能以较低的时间复杂度扩展得到区间$[L-1,R ...
- 2038: [2009国家集训队]小Z的袜子(hose) (莫队算法)
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 专题练习: http://acm.hust.edu.cn/vjudge/conte ...
- BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...
- BZOJ 2038: [2009国家集训队]小Z的袜子
二次联通门 : BZOJ 2038: [2009国家集训队]小Z的袜子 /* BZOJ 2038: [2009国家集训队]小Z的袜子 莫队经典题 但是我并不认为此题适合入门.. Answer = ∑ ...
- BZOJ_2038_[2009国家集训队]小Z的袜子(hose)_莫队
BZOJ_2038_[2009国家集训队]小Z的袜子(hose)_莫队 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无 ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
随机推荐
- FastApi 进阶
前言 终于有了第一个使用 FastApi 编写的线上服务, 在开发的过程中还是遇到了些问题, 这里记录一下 正文 目录结构 我们知道, FastApi 的启动方式推荐使用 uvicorn, 其启动方式 ...
- JVM-03
目录 1.1 新生代垃圾收集器 1.1.1 Serial 垃圾收集器(单线程) 1.1.2 ParNew 垃圾收集器(多线程) 1.1.3 Parallel Scavenge 垃圾收集器(多线程) 2 ...
- 【Flutter】功能型组件之异步UI更新
前言 很多时候会依赖一些异步数据来动态更新UI,比如在打开一个页面时我们需要先从互联网上获取数据,在获取数据的过程中我们显示一个加载框,等获取到数据时我们再渲染页面:又比如想展示Stream(比如文件 ...
- MySQL45讲:一条update语句是怎样执行的
首先创建一张表: create table T(ID int primary key,c int); 如果要更新ID=2这行+1:应该这样写 update T set c=c+1 where ID=2 ...
- python模块详解 | shutil
简介: shutil是python的一个内置模块,提供了许多关于文件和文件集合的高级操作,特别提供文件夹与文件操作.归档操作了支持文件复制和删除的功能. 文件夹与文件操作: copyfileobj(f ...
- 在JavaScript种遇到这样的错误如何解决XML 解析错误:格式不佳 位置:http:/... 行 27,列 32:
相信很多人在开发的过程中都会遇到在js中解析xml文档的问题.有时候文档解析失败,但就是不知道怎么失败的,哪里格式不对.这里教大家一个方法来排查JavaScript解析xml文档格式出错的办法. 1. ...
- 【Linux】CentOS7中yumbackend.py进程的结束方法
环境: CentOS Linux release 7.3.1611 (Core) 今天启动这个不怎么用的机器,才启动,就发现后台的yum无法进行安装,持续报这个错误 Loaded plugins: f ...
- C# 合并和拆分PDF文件
一.合并和拆分PDF文件的方式 PDF文件使用了工业标准的压缩算法,易于传输与储存.它还是页独立的,一个PDF文件包含一个或多个"页",可以单独处理各页,特别适合多处理器系统的工作 ...
- 【链表】leetcode-1290-二进制链表转整数
leetcode-1290-二进制链表转整数 题目描述 给你一个单链表的引用结点 head.链表中每个结点的值不是 0 就是 1.已知此链表是一个整数数字的二进制表示形式. 请你返回该链表所表示数字的 ...
- 使用Python的pandas模块、mplfinance模块、matplotlib模块绘制K线图
目录 pandas模块.mplfinance模块和matplotlib模块介绍 pandas模块 mplfinance模块和matplotlib模块 安装mplfinance模块.pandas模块和m ...