【Luogu】P2709小B的询问(莫队算法)
md,1A率等于0.
烦死。
终于搞到一道莫队了qwq。
先对区间分块再按照块编号为第一关键字,右端点为第二关键字排序,然后每次端点移动1乱搞。
然后……就wa了。
然后有很多细节需要注意qwq。比如这是个离线算法,在线输出个鬼
当然更有可能是我太菜了
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #include<cmath> using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } long long nu[51000]; long long d[1000010]; int s[1000100]; int la[1000100]; int ans[1000100]; long long sum; struct Que{ long long x,y; int id; bool operator <(const Que a){ if(s[x]!=s[a.x]) return s[x]<s[a.x]; else return y<a.y; } }que[1000010]; int main(){ int n=read(),m=read(),q=read(); int b=sqrt(n); for(int i=1;i<=n;++i){ d[i]=read(); s[i]=(i-1)/b+1; } for(int i=1;i<=m;++i) que[i]=(Que){read(),read(),i}; sort(que+1,que+m+1); for(int i=m;i;--i) la[s[que[i].x]]=i; long long sum=1; nu[0]=1; int l=0,r=0; for(int j=1;j<=m;++j){ int x=que[j].x,y=que[j].y; while(r<y){ r++; sum-=nu[d[r]]*nu[d[r]]; nu[d[r]]++; sum+=nu[d[r]]*nu[d[r]]; } while(r>y){ sum-=nu[d[r]]*nu[d[r]]; nu[d[r]]--; sum+=nu[d[r]]*nu[d[r]]; r--; } while(l<x){ sum-=nu[d[l]]*nu[d[l]]; nu[d[l]]--; sum+=nu[d[l]]*nu[d[l]]; l++; } while(l>x){ l--; sum-=nu[d[l]]*nu[d[l]]; nu[d[l]]++; sum+=nu[d[l]]*nu[d[l]]; } ans[que[j].id]=sum; } for(int i=1;i<=m;++i) printf("%lld\n",ans[i]); return 0; } /* 6 4 3 1 3 2 1 1 3 1 4 5 6 3 5 2 6 */