BZOJ 2038 小Z的袜子(hose) (莫队离线)
2015-07-24 11:34
190 查看
题目地址:BZOJ 2038
裸的莫队算法。
代码如下:
裸的莫队算法。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> #include <time.h> using namespace std; #define LL long long #define pi acos(-1.0) #pragma comment(linker, "/STACK:1024000000") const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; const int MAXN=50000+10; int a[MAXN], ha[MAXN]; LL ans1[MAXN], ans2[MAXN]; struct node { int l, r, id, pos; }fei[MAXN]; LL gcd(LL x, LL y) { return y==0?x:gcd(y,x%y); } bool cmp(node x, node y) { return x.pos<y.pos||(x.pos==y.pos&&x.r<y.r); } int main() { int n, m, i, j, l, r, k; LL res, Gcd; while(scanf("%d%d",&n,&m)!=EOF){ for(i=1;i<=n;i++){ scanf("%d",&a[i]); } k=sqrt(n*1.0)+0.5; for(i=0;i<m;i++){ scanf("%d%d",&fei[i].l,&fei[i].r); fei[i].id=i; fei[i].pos=fei[i].l/k; } sort(fei,fei+m,cmp); memset(ha,0,sizeof(ha)); l=1; r=0; res=0; for(i=0;i<m;i++){ while(r>fei[i].r){ res-=(LL)ha[a[r]]-1; ha[a[r]]--; r--; } while(r<fei[i].r){ r++; ha[a[r]]++; res+=(LL)ha[a[r]]-1; } while(l>fei[i].l){ l--; ha[a[l]]++; res+=(LL)ha[a[l]]-1; } while(l<fei[i].l){ res-=(LL)ha[a[l]]-1; ha[a[l]]--; l++; } ans1[fei[i].id]=res; ans2[fei[i].id]=(LL)(r-l+1)*(r-l)/2; } for(i=0;i<m;i++){ if(!ans1[i]){ puts("0/1"); continue; } Gcd=gcd(ans1[i],ans2[i]); printf("%lld/%lld\n",ans1[i]/Gcd,ans2[i]/Gcd); } } return 0; }