bzoj3781(莫队板子)

来源:互联网 发布:linux内网通外网不通 编辑:程序博客网 时间:2024/05/01 21:31

就是练一练莫队的基本结构。。。无思维含量。。。

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;const int N=50005;int n,m,k;int a[N],pos[N];ll c[N],ans,ml,mr;struct aa{int l,r,id;ll ans;}q[N];bool cmp1(aa a,aa b){if (pos[a.l]!=pos[b.l]) return pos[a.l]<pos[b.l];return a.r<b.r;}bool cmp2(aa a,aa b){return a.id<b.id;}void updata(int i,int add){ans-=c[a[i]]*c[a[i]];c[a[i]]+=add;ans+=c[a[i]]*c[a[i]];}void solve(){ml=1;mr=0;for (int i=1;i<=m;i++){for (;mr>q[i].r;mr--) updata(mr,-1);//莫队一定要先移动右端点for (;mr<q[i].r;mr++) updata(mr+1,1);for (;ml<q[i].l;ml++) updata(ml,-1);for (;ml>q[i].l;ml--) updata(ml-1,1);q[i].ans=ans;}}int main(){scanf("%d%d%d",&n,&m,&k);int block=int(sqrt(n*1.0));for (int i=1;i<=n;i++) pos[i]=(i-1)/block+1;for (int i=1;i<=n;i++) scanf("%d",&a[i]);for (int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;sort(q+1,q+m+1,cmp1);solve();sort(q+1,q+m+1,cmp2);for (int i=1;i<=m;i++) printf("%lld\n",q[i].ans);return 0;} 


 

0 0