区间求和【莫队板子题】牛客小白月赛17
题目:给你n个数,每个数为ai,现在有m个询问,每个询问l,r,需要求出:代表ai在这个区间中出现的次数。
题目链接:https://ac.nowcoder.com/acm/contest/1085/G
输入:
10 5 1 3 2 4 5 6 4 5 6 7 1 5 2 5 3 4 1 10 3 7
输出:
15 14 6 73 29
参考博客:1.https://www.cnblogs.com/MisakaAzusa/p/8684319.html
2.https://www.cnblogs.com/WAMonster/p/10118934.html
AC代码:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define int long long 5 #define N 100020 6 int belong[N]; 7 int arr[N]; 8 int sum[N]; 9 int vis[N]; 10 int res; 11 int B; 12 struct str{ 13 int l,r,id; 14 bool operator<(const str &c)const 15 { 16 return l/B==c.l/B?r<c.r:l<c.l; 17 } 18 }st[N]; 19 void add(int pos) { 20 res-=vis[pos]*vis[pos]*pos; 21 vis[pos]++; 22 res+=vis[pos]*vis[pos]*pos; 23 } 24 void del(int pos) { 25 res-=vis[pos]*vis[pos]*pos; 26 vis[pos]--; 27 res+=vis[pos]*vis[pos]*pos; 28 } 29 signed main(){ 30 int n,m; 31 scanf("%lld%lld",&n,&m); 32 B = sqrt(n); 33 34 for(int i=1;i<=n;i++) 35 scanf("%lld",&arr[i]); 36 for(int i=1;i<=m;i++){ 37 int l,r; 38 scanf("%lld%lld",&l,&r); 39 st[i].l=l; 40 st[i].r=r; 41 st[i].id=i; 42 } 43 sort(st+1,st+1+m); 44 res=0; 45 int l=1; 46 int r=0; 47 for(int i=1;i<=m;i++){ 48 int ql=st[i].l; 49 int qr=st[i].r; 50 while(l < ql) del(arr[l++]); 51 while(l > ql) add(arr[--l]); 52 while(r < qr) add(arr[++r]); 53 while(r > qr) del(arr[r--]); 54 sum[st[i].id]=res; 55 } 56 for(int i=1;i<=m;i++){ 57 printf("%lld\n",sum[i]); 58 } 59 return 0; 60 }