bzoj 3781: 小B的询问 莫队算法+分块
2016-11-09 10:55
351 查看
题意
有一个序列,包含N个1~K之间的整数。一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。n,m,k<=50000
分析
莫队算法好劲啊!!!按所在块为第一关键字,右端点为第二关键字对询问排序,然后就可以直接上莫队啦。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define ll long long #define N 50005 using namespace std; int n,m,cnt,cnt1,t ,a ,pos ,k,block; struct data{int id,x,y;ll ans;}q ; ll ans; bool cmp(data a,data b) { return pos[a.x]<pos[b.x]||pos[a.x]==pos[b.x]&&a.y<b.y; } bool cmpid(data a,data b) { return a.id<b.id; } void updata(int x,int y) { ans-=(ll)t[a[x]]*t[a[x]]; t[a[x]]+=y; ans+=(ll)t[a[x]]*t[a[x]]; } void query() { updata(1,1); for (int i=1,l=1,r=1;i<=m;i++) { for (;r<q[i].y;r++) updata(r+1,1); for (;l>q[i].x;l--) updata(l-1,1); for (;r>q[i].y;r--) updata(r,-1); for (;l<q[i].x;l++) updata(l,-1); q[i].ans=ans; } } int main() { scanf("%d%d%d",&n,&m,&k); block=sqrt(n); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); pos[i]=(i+block-1)/block; } for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); q[i].x=x;q[i].y=y;q[i].id=i; } sort(q+1,q+m+1,cmp); query(); sort(q+1,q+m+1,cmpid); for (int i=1;i<=m;i++) printf("%lld\n",q[i].ans); return 0; }
相关文章推荐
- 【模板】BZOJ 3781: 小B的询问 莫队算法
- bzoj 3781 小B的询问(莫队算法)
- 【BZOJ3781】小B的询问【莫队算法】
- 【莫队算法】bzoj3781 小B的询问
- 【BZOJ】3781: 小B的询问(莫队算法)
- Bzoj 3781: 小B的询问 莫队,分块,暴力
- BZOJ 3781 小B的询问 序列莫队算法
- BZOJ - 3781 小B的询问 莫队算法
- 【P2709】【BZOJ3781】 小B的询问 莫队算法
- BZOJ 3781: 小B的询问 莫队算法
- 【bzoj3781】小B的询问 莫队算法
- BZOJ 3781 莫队算法
- BZOJ 3781: 小B的询问 | 莫队
- BZOJ3781【莫队算法】
- BZOJ3781 小B的询问 题解&代码 【附莫队总结】
- 【莫队算法】【权值分块】bzoj3585 mex
- [bzoj3781]小B的询问 智障莫队
- bzoj 3781: 小B的询问(莫队)
- BZOJ 3809 Gty的二逼妹子序列 莫队算法+分块
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)|分块|莫队算法