BZOJ 2038 小Z的袜子 莫队算法
2013-03-03 20:48
295 查看
题解:
区间总的方案数是可以算的,只要求相同的颜色的方案数即可。(数学中讲的古典概型??)
我不知道我写的是不是莫队算法,时间还是很快的。。
话说,这题稍微优化的暴力也能过。
看了别人的介绍莫队算法的文章没有看太懂,也不知道这个神奇的复杂度是怎么证明的。。。
我大致是这样做的:
1、分块
2、把所有询问左端点排序
3、对于左端点在同一块内的询问按右端点排序,然后分三种情况统计。
传说中这样复杂度是nsqrt(n)的,但是我怎么觉得这个和我的暴力差不多。。。。
莫名其妙跑的这么快。。。
View Code
这个莫队算法是处理区间无修改询问的通用算法??
区间总的方案数是可以算的,只要求相同的颜色的方案数即可。(数学中讲的古典概型??)
我不知道我写的是不是莫队算法,时间还是很快的。。
话说,这题稍微优化的暴力也能过。
看了别人的介绍莫队算法的文章没有看太懂,也不知道这个神奇的复杂度是怎么证明的。。。
我大致是这样做的:
1、分块
2、把所有询问左端点排序
3、对于左端点在同一块内的询问按右端点排序,然后分三种情况统计。
传说中这样复杂度是nsqrt(n)的,但是我怎么觉得这个和我的暴力差不多。。。。
莫名其妙跑的这么快。。。
View Code
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #define N 55555 using namespace std; struct Q { long long l,r,id; }q ; struct ANS { long long a,b; void in(long long x,long long y) {a=x,b=y;} }ans ; long long col ,n,m,gs ; long long lt ,rt ,len,tot; inline bool cmpl(const Q &a,const Q &b) { return a.l<b.l; } inline bool cmpr(const Q &a,const Q &b) { return a.r<b.r; } inline void read() { scanf("%lld%d",&n,&m); for(long long i=1;i<=n;i++) scanf("%lld",&col[i]); for(long long i=1;i<=m;i++) { scanf("%lld%d",&q[i].l,&q[i].r); q[i].id=i; } len=(long long)sqrt(1.0*n); tot=n/len; for(long long i=1;i<=tot;i++) lt[i]=rt[i-1]+1,rt[i]=rt[i-1]+len; if(rt[tot]!=n) lt[tot+1]=rt[tot]+1,rt[tot+1]=n,tot++; } inline long long gcd(long long x,long long y) { long long ys; while(y) { ys=x%y; x=y; y=ys; } return x; } inline void getans(long long x,long long ml) { long long sum=(q[x].r-q[x].l)*(q[x].r-q[x].l+1)/2; long long mx=gcd(ml,sum); if(!mx) ans[q[x].id].in(0,1); else ans[q[x].id].in(ml/mx,sum/mx); } inline void go() { sort(q+1,q+m+1,cmpl); long long s=1,t=1; for(long long i=1,ml=0;i<=tot;i++,ml=0) { memset(gs,0,sizeof gs); while(s<=m&&q[s].l<lt[i]) s++; while(t<=m&&q[t].l<=rt[i]) t++; if(s>m||q[s].l>rt[i]) continue; sort(q+s,q+t,cmpr); for(long long j=q[s].l;j<=q[s].r;j++) ml+=gs[col[j]],gs[col[j]]++; getans(s,ml); for(long long j=s+1;j<t;j++) { if(q[j].l<q[j-1].l) { for(long long k=q[j].l;k<q[j-1].l;k++) ml+=gs[col[k]],gs[col[k]]++; for(long long k=q[j-1].r+1;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++; } else if(q[j].l>q[j-1].r) { for(long long k=q[j-1].l;k<=q[j-1].r;k++) gs[col[k]]--; ml=0; for(long long k=q[j].l;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++; } else { for(long long k=q[j-1].l;k<q[j].l;k++) gs[col[k]]--,ml-=gs[col[k]]; for(long long k=q[j-1].r+1;k<=q[j].r;k++) ml+=gs[col[k]],gs[col[k]]++; } getans(j,ml); } } for(long long i=1;i<=m;i++) printf("%lld/%lld\n",ans[i].a,ans[i].b); } int main() { read(),go(); return 0; }
这个莫队算法是处理区间无修改询问的通用算法??
相关文章推荐
- BZOJ - 2038 小Z的袜子 莫队算法
- 莫队算法(小Z的袜子,BZOJ 2038)
- BZOJ 2038 2009国家集训队 小Z的袜子(hose) 莫队算法
- bzoj 2038 小Z的袜子(hose)(莫队算法)
- BZOJ 2038 [2009国家集训队] 小Z的袜子 莫队算法
- 小Z的袜子(hose) - bzoj 2038 莫队算法
- [bzoj 2038 OR 清橙A1206 小Z的袜子]莫队算法
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法】
- bzoj 2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ 2038 小Z的袜子(hose) [莫队算法]
- 莫队算法—【清ojA1206】【bzoj2038】小Z的袜子
- bzoj 2038: [2009国家集训队]小Z的袜子(hose) 【莫队算法】
- bzoj 2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ 2038: [2009国家集训队]小Z的袜子(莫队算法例题)
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)&&莫队算法
- BZOJ 2038 小Z的袜子 莫队算法(模板题)
- BZOJ 2038 小Z的袜子 (莫队算法)
- BZOJ 2038 小Z的袜子(hose)(莫队算法)
- BZOJ 2038 小Z的袜子(莫队算法)
- bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队算法