Powerful array(CF-86D)
Problem Description
An array of positive integers a1,?a2,?...,?an is given. Let us consider its arbitrary subarray al,?al?+?1...,?ar, where 1?≤?l?≤?r?≤?n. For every positive integer s denote by Ks the number of occurrences of s into the subarray. We call the power of the subarray the sum of products Ks·Ks·s for every positive integer s. The sum contains only finite number of nonzero summands as the number of different values in the array is indeed finite.
You should calculate the power of t given subarrays.
Input
First line contains two integers n and t (1?≤?n,?t?≤?200000) — the array length and the number of queries correspondingly.
Second line contains n positive integers ai (1?≤?ai?≤?106) — the elements of the array.
Next t lines contain two positive integers l, r (1?≤?l?≤?r?≤?n) each — the indices of the left and the right ends of the corresponding subarray.
Output
Output t lines, the i-th line of the output should contain single positive integer — the power of the i-th query subarray.
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preferred to use cout stream (also you may use %I64d).
Examples
Input
3 2
1 2 1
1 2
1 3
Output
3
6
Input
8 3
1 1 2 2 1 3 1 1
2 7
1 6
2 7
Output
20
20
20
Note
Consider the following array (see the second sample) and its [2, 7] subarray (elements of the subarray are colored):
Then K1?=?3, K2?=?2, K3?=?1, so the power is equal to 32·1?+?22·2?+?12·3?=?20.
題意:一個長度為 n 的數字序列,m 次詢問,每次詢問給出一個區間 [l,r],求這個區間內出現過的值與其次數平方的乘積的和
思路:普通莫隊模版題,要求每個區間出現過的值與其出現次數平方的乘積的和,只需修改 O(1) 部分即可
Source Program
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #define PI acos(-1.0) #define E 1e-9 #define INF 0x3f3f3f3f #define LL long long const int MOD=10007; const int N=1000000+5; const int dx[]= {-1,1,0,0}; const int dy[]= {0,0,-1,1}; using namespace std;struct Node{int l,r;//詢問的左右端點int id;//詢問的編號 }q[N]; int n,m,a[N]; int block;//分塊 LL ans,cnt[N*2]; LL res[N];bool cmp(Node a,Node b){//奇偶性排序return (a.l/block)^(b.l/block)?a.l<b.l:(((a.l/block)&1)?a.r<b.r:a.r>b.r); }void add(int x){ans-=cnt[a[x]]*cnt[a[x]]*a[x];//減去舊的cnt[a[x]]++;ans+=cnt[a[x]]*cnt[a[x]]*a[x];//加上新的 } void del(int x){ans-=cnt[a[x]]*cnt[a[x]]*a[x];//減去舊的cnt[a[x]]--;ans+=cnt[a[x]]*cnt[a[x]]*a[x];//加上新的 }int main(){while(scanf("%d%d",&n,&m)!=EOF){memset(cnt,0,sizeof(cnt));ans=0;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;}block=sqrt(m*2/3*1.0);//分塊,卡常數sort(q+1,q+m+1,cmp);//對詢問進行排序int l=1,r=0;//左右指針for(int i=1;i<=m;i++){int ql=q[i].l,qr=q[i].r;//詢問的左右端點while(l>ql) add(--l);while(r<qr) add(++r);while(l<ql) del(l++);while(r>qr) del(r--);res[q[i].id]=ans;//獲取答案}for(int i=1;i<=m;i++)printf("%lld\n",res[i]);}return 0; }?
總結
以上是生活随笔為你收集整理的Powerful array(CF-86D)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数列分块入门 1(LibreOj-627
- 下一篇: Two Strings(CF-223B)