CodeForces 86D Powerful array
莫队算法。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=200000+10; int n,t,a[maxn],cnt[maxn*10],pos[maxn]; struct X { int l,r,id; }s[maxn]; int L,R; long long Ans,f[maxn]; bool cmp(const X&a,const X&b) { if(pos[a.l]==pos[b.l]) return a.r<b.r; return pos[a.l]<pos[b.l]; } int main() { scanf("%d",&n); scanf("%d",&t); int sz=900; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); pos[i]=i/sz; } for(int i=1;i<=t;i++) { scanf("%d%d",&s[i].l,&s[i].r); s[i].id=i; } sort(s+1,s+1+t,cmp); for(int i=s[1].l;i<=s[1].r;i++) { Ans=Ans+(1+2*cnt[a[i]])*a[i]; cnt[a[i]]++; } f[s[1].id]=Ans; L=s[1].l; R=s[1].r; for(int i=2;i<=t;i++) { while(L<s[i].l) { Ans=Ans+(1-2*cnt[a[L]])*a[L]; cnt[a[L]]--; L++; } while(L>s[i].l) { L--; Ans=Ans+(1+2*cnt[a[L]])*a[L]; cnt[a[L]]++; } while(R>s[i].r) { Ans=Ans+(1-2*cnt[a[R]])*a[R]; cnt[a[R]]--; R--; } while(R<s[i].r) { R++; Ans=Ans+(1+2*cnt[a[R]])*a[R]; cnt[a[R]]++; } f[s[i].id]=Ans; } for(int i=1;i<=t;i++) printf("%lld\n",f[i]); return 0; }