题意:求区间[l, r] 内的数的出现次数的平方 * 该数字。
题解:莫队离线操作, 然后加减位置的时候直接修改答案就好了。
这个题目中发现了一个很神奇的事情,本来数组开1e6大小就直接过了4100+ms, 想测试一下inline,顺手把空间砍成了刚好够用,然后跑的更慢了 4700+ms,删了inline之后T了,到现在也不知道发生了啥。
如果有大牛路过希望帮我看下, CF run id 38822420(4100+) 38822607(4700+)38822636(TLE)。然后就是我空间稍微开大一点就跑的更快了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define max3(a,b,c) max(a,max(b,c)) 12 #define min3(a,b,c) min(a,min(b,c)) 13 #define _S(X) cout << x << ' '; 14 #define __S(x) cout << x << endl; 15 typedef pair<int,int> pll; 16 const int INF = 0x3f3f3f3f; 17 const LL mod = (int)1e9+7; 18 const int N = 8e6+ 100; 19 int n, m, blo; 20 int cnt[N]; 21 int a[N]; 22 LL ans[N]; 23 LL tmp; 24 struct Node{ 25 int l, r; 26 int id; 27 }q[N]; 28 void Add(int p){ 29 tmp -= 1ll * a[p] * cnt[a[p]] * cnt[a[p]]; 30 cnt[a[p]]++; 31 tmp += 1ll * a[p] * cnt[a[p]] * cnt[a[p]]; 32 } 33 void Remove(int p){ 34 tmp -= 1ll * a[p] * cnt[a[p]] * cnt[a[p]]; 35 cnt[a[p]]--; 36 tmp += 1ll * a[p] * cnt[a[p]] * cnt[a[p]]; 37 } 38 bool cmp(Node x1, Node x2){ 39 if(x1.l/blo != x2.l/blo) 40 return x1.l/blo < x2.l / blo; 41 return x1.r < x2.r; 42 } 43 int main(){ 44 scanf("%d%d", &n, &m); 45 blo = sqrt(n); 46 for(int i = 1; i <= n; i++) 47 scanf("%d", &a[i]); 48 for(int i = 1; i <= m; i++){ 49 scanf("%d%d", &q[i].l, &q[i].r); 50 q[i].id = i; 51 } 52 sort(q+1, q+1+m, cmp); 53 int nL = 0, nR = 0, tL, tR; 54 for(int i = 1; i <= m; i++){ 55 tL = q[i].l, tR = q[i].r; 56 while(nL < tL) Remove(nL++); 57 while(nL > tL) Add(--nL); 58 while(nR <= tR) Add(nR++); 59 while(nR > tR+1) Remove(--nR); 60 ans[q[i].id] = tmp; 61 } 62 for(int i = 1; i <= m; i++){ 63 printf("%I64d ", ans[i]); 64 } 65 return 0; 66 }