我的第一道莫队题。
以后新学一个算法做的第一题尽量都写一个博客。
其实非常简单,没有什么好讲的。
反正莫队的核心就是分块排序,然后移动选定区间指针,添加或删除元素嘛。
当然因为这是一道莫队门槛题,所以比较简单。
#include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 50010 using namespace std; typedef long long LL; int n,m,k,pos[MAXN],a[MAXN],cnt[MAXN]; LL sum,ans[MAXN]; struct Ques{ int l,r,id; LL ans; }q[MAXN]; bool cmp1(Ques x,Ques y){return pos[x.l]<pos[y.l]||pos[x.l]==pos[y.l]&&x.r<y.r;} int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} return x*f; } void add(int x){ if(x<1||x>k) return; sum+=2*cnt[x]+1; cnt[x]++; } void del(int x){ if(x<1||x>k) return; sum-=2*cnt[x]-1; cnt[x]--; } int main(){ n=read();m=read();k=read(); int sz=sqrt(n); for(int i=1;i<=n;i++) a[i]=read(),pos[i]=i/sz; for(int i=1;i<=m;i++) {q[i].l=read();q[i].r=read();q[i].id=i;} sort(q+1,q+m+1,cmp1); int L=0,R=0; for(int i=1;i<=m;i++){ while(R<q[i].r) add(a[R+1]),R++; while(R>q[i].r) del(a[R]),R--; while(L<q[i].l) del(a[L]),L++; while(L>q[i].l) add(a[L-1]),L--; ans[q[i].id]=sum; } for(int i=1;i<=m;i++) printf("%lld ",ans[i]); return 0; }