【莫队算法】bzoj3781 小B的询问
2014-11-28 15:58
302 查看
莫队经典。 开个数组维护a[i]出现的次数。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; int Num,CH[12],f,c; inline void R(int &x){ c=0;f=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0'); x*=f; } inline void P(int x){ if(x<10)putchar(x+'0'); else{P(x/10);putchar(x%10+'0');} } int ans,anss[50001]; int n,m,K,num[50001],a[50001],T[50001]; int sqr(const int &x){return x*x;} struct ASK{int l,r,p;void Read(){R(l);R(r);}}Q[50001]; bool operator < (const ASK &a,const ASK &b){return num[a.l]!=num[b.l] ? num[a.l]<num[b.l] : a.r<b.r;} void makeblock() { int sz=sqrt(n),sum=1; if(!sz) sz=1; for(;sum*sz<n;++sum) { int r=sum*sz; for(int i=sz*(sum-1)+1;i<=r;++i) num[i]=sum; } for(int i=sz*(sum-1)+1;i<=n;++i) num[i]=sum; } int main() { R(n);R(m);R(K);makeblock(); for(int i=1;i<=n;++i) R(a[i]); for(int i=1;i<=m;++i) {Q[i].Read(); Q[i].p=i;} sort(Q+1,Q+m+1); for(int i=Q[1].l;i<=Q[1].r;++i){ans-=sqr(T[a[i]]);ans+=sqr(++T[a[i]]);} anss[Q[1].p]=ans; for(int i=2;i<=m;++i) { if(Q[i].l<Q[i-1].l){for(int j=Q[i-1].l-1;j>=Q[i].l;--j){ans-=sqr(T[a[j]]);ans+=sqr(++T[a[j]]);}} else{for(int j=Q[i-1].l;j<Q[i].l;++j){ans-=sqr(T[a[j]]);ans+=sqr(--T[a[j]]);}} if(Q[i].r<Q[i-1].r){for(int j=Q[i-1].r;j>Q[i].r;--j){ans-=sqr(T[a[j]]);ans+=sqr(--T[a[j]]);}} else{for(int j=Q[i-1].r+1;j<=Q[i].r;++j){ans-=sqr(T[a[j]]);ans+=sqr(++T[a[j]]);}} anss[Q[i].p]=ans; } for(int i=1;i<=m;++i) P(anss[i]),puts(""); return 0; }
相关文章推荐
- 【BZOJ3781】小B的询问【莫队算法】
- 【bzoj3781】小B的询问 莫队算法
- BZOJ 3781 小B的询问 序列莫队算法
- bzoj 3781 小B的询问(莫队算法)
- 【P2709】【BZOJ3781】 小B的询问 莫队算法
- BZOJ 3781: 小B的询问 莫队算法
- bzoj 3781: 小B的询问 莫队算法+分块
- 【模板】BZOJ 3781: 小B的询问 莫队算法
- BZOJ - 3781 小B的询问 莫队算法
- 【BZOJ】3781: 小B的询问(莫队算法)
- BZOJ 5016: [Snoi2017]一个简单的询问 莫队算法
- BZOJ[3781]小B的询问 莫队
- BZOJ 3781: 小B的询问 [莫队]
- 【BZOJ】3781 小B的询问 莫队
- BZOJ3781 小B的询问 莫队
- BZOJ 3781 莫队算法
- LOJ2254 && bzoj5016 [Snoi2017]一个简单的询问 莫队算法
- BZOJ3781【莫队算法】
- bzoj3781 小B的询问 莫队
- BZOJ3781 小B的询问 题解&代码 【附莫队总结】