【BZOJ】2038 小Z的袜子
来源:互联网 发布:python product 函数 编辑:程序博客网 时间:2024/06/11 23:41
Problem
【题意】在长度为
【数据范围】
Analysis
莫队算法怎么做?百度一下随便点开即可。
本身做这道题就是为了打一遍模板,然后复习一下复杂度分析,用来准备分析一下强制在线莫队的复杂度和
然而模板不小心打错了,”
下面开始分析复杂度。
先是把询问排序,我的写法:
第一关键字是
第二关键字是
时间复杂度为
然后是莫队算法。
①当
时间复杂度为:
②当
时间复杂度为:
③当
时间复杂度为:
综上所述,总的时间复杂度为:
回顾上述的分析方法,也就是按照块内外、不同的端点分类讨论而已。
Question
其实看了VFK糖果公园的题解,我还想到了一个问题:
排序的时候,第一关键字为
其实是可以的,这里再来一次分析当练习。
分以下
①当
②当
③当
④当
综上所述,时间复杂度为
Code
【代码1】
排序方式:
第一关键字:
第二关键字:
实测:2080 ms
#include <cstdio>#include <cctype>#include <cmath>#include <algorithm>using namespace std;typedef long long Lint;const int N=65536;const int M=65536;int n;int a[N];int m;int unit;struct Ques{ int l,r,id; friend inline int operator < (Ques qa,Ques qb) { return qa.l/unit!=qb.l/unit?qa.l/unit<qb.l/unit:qa.r<qb.r; }}q[M];Lint ans[M][2];int cnt[N];int l=1,r=0;Lint res;inline int read(void){ int x=0,f=1; char c=getchar(); for (;!isdigit(c);c=getchar()) if (c=='-') f=-1; for (;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;}inline void add(int w,int k){ res-=(Lint)cnt[w]*(cnt[w]-1)>>1; cnt[w]+=k; res+=(Lint)cnt[w]*(cnt[w]-1)>>1;}inline Lint gcd(Lint i,Lint j){ for (Lint r;j;r=i%j,i=j,j=r); return i;}int main(void){ n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; unit=(int)sqrt(n); sort(q+1,q+m+1); Lint g; for (int i=1;i<=m;i++) { for (;l<q[i].l;l++) add(a[l],-1); for (;l>q[i].l;l--) add(a[l-1],1); for (;r<q[i].r;r++) add(a[r+1],1); for (;r>q[i].r;r--) add(a[r],-1); ans[q[i].id][0]=res,ans[q[i].id][1]=(Lint)(q[i].r-q[i].l+1)*(q[i].r-q[i].l)>>1; g=gcd(ans[q[i].id][0],ans[q[i].id][1]); for (int k=0;k<=1;k++) ans[q[i].id][k]/=g; } for (int i=1;i<=m;i++) printf("%lld/%lld\n",ans[i][0],ans[i][1]); return 0;}
【代码2】
排序方式:
第一关键字:
第二关键字:
实测:2396 ms
#include <cstdio>#include <cctype>#include <cmath>#include <algorithm>using namespace std;typedef long long Lint;const int N=65536;const int M=65536;int n;int a[N];int m;int unit;struct Ques{ int l,r,id; friend inline int operator < (Ques qa,Ques qb) { return qa.l/unit!=qb.l/unit?qa.l/unit<qb.l/unit:qa.r/unit<qb.r/unit; }}q[M];Lint ans[M][2];int cnt[N];int l=1,r=0;Lint res;inline int read(void){ int x=0,f=1; char c=getchar(); for (;!isdigit(c);c=getchar()) if (c=='-') f=-1; for (;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;}inline void add(int w,int k){ res-=(Lint)cnt[w]*(cnt[w]-1)>>1; cnt[w]+=k; res+=(Lint)cnt[w]*(cnt[w]-1)>>1;}inline Lint gcd(Lint i,Lint j){ for (Lint r;j;r=i%j,i=j,j=r); return i;}int main(void){ n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; unit=(int)sqrt(n); sort(q+1,q+m+1); Lint g; for (int i=1;i<=m;i++) { for (;l<q[i].l;l++) add(a[l],-1); for (;l>q[i].l;l--) add(a[l-1],1); for (;r<q[i].r;r++) add(a[r+1],1); for (;r>q[i].r;r--) add(a[r],-1); ans[q[i].id][0]=res,ans[q[i].id][1]=(Lint)(q[i].r-q[i].l+1)*(q[i].r-q[i].l)>>1; g=gcd(ans[q[i].id][0],ans[q[i].id][1]); for (int k=0;k<=1;k++) ans[q[i].id][k]/=g; } for (int i=1;i<=m;i++) printf("%lld/%lld\n",ans[i][0],ans[i][1]); return 0;}
Sumarize
首先是写莫队需要注意的一个地方:
在排序的时候,不要把”
然后是莫队算法的排序方式:
按块来分,最后一个关键字可以直接从小到大。
近而回顾离线算法的排序方式。本来是这样的:
①按照左端点排序 ②按照右端点排序 ③按照块排序
现在可以补充一点,就是说我们可以使用多关键字排序。
然后是莫队的复杂度分析的方法:
按照不同端点、块内外来分类讨论。
就这些了,希望不要再因为类似的错误导致一个上午的颓废。
- BZOJ 2038: 小Z的袜子
- BZOJ 2038小Z的袜子 分块
- BZOJ 2038 小z的袜子
- bzoj-2038 小Z的袜子 hose
- BZOJ 2038 小Z的袜子(hose)
- BZOJ 2038 小Z的袜子
- 【BZOJ】2038 小Z的袜子
- BZOJ 2038 小Z的袜子
- 【BZOJ 2038】小Z的袜子
- BZOJ 2038 小Z的袜子
- BZOJ 2038小z的袜子
- bzoj 2038 小Z的袜子
- bzoj 2038 小Z的袜子 莫队
- bzoj 2038 小z的袜子 莫队
- bzoj 2038 小z的袜子
- bzoj 2038: [2009国家集训队]小Z的袜子(hose)
- 【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose)
- 线性莫队算法 BZOJ 2038 小Z的袜子
- Lua学习笔记-数据结构
- 【自己总结的】HBase基本命令
- listview之adapter的优化
- List 去重(java)
- Java基本API--思维导图
- 【BZOJ】2038 小Z的袜子
- RandomStringUtils生成随机数
- VTK大体流程
- (viewpager)adapter的创建
- 指针使用
- C++中的右值引用"&&"
- java定时任务实现的几种方式
- ReactiveCocoa - iOS开发的新框架
- JDK1.8.0_66覆盖原有JDK7环境变量