Codeforces#86D Powerful array(分块暴力)

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 lr (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).

Sample Input

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

题意:就问问你统计[L,R]中x1,x2,,xi出现次数a1,a2,,ai的ai*ai*xi和。

题解:分块暴力。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef __int64 LL;
const int INF = 0x3f3f3f3f;
const int maxn=200000+100;
LL up[maxn];
int col[maxn],sum[maxn*10],n,m,k;
LL ans;
struct node{
    int l,r;
    int id;
}q[maxn];
int cmp(node l1,node l2)
{
    if(l1.l/k==l2.l/k)
        return l1.r<l2.r;
    return l1.l<l2.l;
}
void update(int x,int val)
{
    ans-=(LL)col[x]*sum[col[x]]*sum[col[x]];
    sum[col[x]]+=val;
    ans+=(LL)col[x]*sum[col[x]]*sum[col[x]];
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        CLEAR(sum,0);
        k=sqrt(n*1.0+0.5);
        REPF(i,1,n)
            scanf("%d",&col[i]);
        REP(i,m)
        {
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        sort(q,q+m,cmp);
        int L=0,R=0;
        ans=0;
        for(int i=0;i<m;i++)
        {
            int id=q[i].id;
            int l=q[i].l;
            int r=q[i].r;
            while(L < l)
            {
                update(L,-1);
                L++;
            }
            while(R > r)
            {
                update(R,-1);
                R--;
            }
            while(L > l)
            {
                L--;
                update(L,1);
            }
            while(R < r)
            {
                R++;
                update(R,1);
            }
            up[id]=ans;
        }
        for(int i=0;i<m;i++)
            printf("%I64d\n",up[i]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 07:13:56

Codeforces#86D Powerful array(分块暴力)的相关文章

【分块】Codeforces 86d Powerful array

通道 题意:询问[l,r]区间的权和,权定义为sum(k^2*a[i]),k表示a[i]出现的次数 思路:区间每增加一个a[i],增量是(2*x+1)*a[i],因为(x+1)^2*a[i] = (x^2 +2*x + 1)*a[i] 分块排序即可,块内按r排序 代码: #include <cstdio> #include <algorithm> #include <cmath> using namespace std; #define N 200100 typedef

Codeforces 86D Powerful array(莫队)

题目链接:http://codeforces.com/problemset/problem/86/D 题目: 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 occu

CodeForces 86D Powerful array(莫队算法)

和BZOJ2038差不多..复习一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 int block; 6 struct Query{ 7 int i,l,r; 8 bool operator<(const Query &q)const{ 9 if(l/block==q.l/block) return r<q.r; 10 re

CodeForces - 86D Powerful array (莫队)

题意:查询的是区间内每个数出现次数的平方×该数值的和. 分析:虽然是道莫队裸体,但是姿势不对就会超时.答案可能爆int,所以要开long long 存答案.一开始的维护操作,我先在res里减掉了a[pos]*cnt[a[pos]]*cnt[a[pos]],将cnt[a[pos]]+1,再将乘积加回.其实根据数学原理,K^2和(K+1)^2差值是2K+1,那么其实每次更新时只要加上或减去a[pos]*(2*cnt[pos]+1)即可,这样更高效. #include<bits/stdc++.h>

86D - Powerful array

莫队. 统计ai[i]的出现次数,每一次先还原贡献,再加上或减去当前的贡献即可. #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<stack> #include<vector> #include<queue> #i

codeforces 86D D. Powerful array(莫队算法)

题目链接: D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input standard input output standard output An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary subarray al, al + 1..., ar, wh

D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力

莫队算法就是优化的暴力算法.莫队算法是要把询问先按左端点属于的块排序,再按右端点排序.只是预先知道了所有的询问.可以合理的组织计算每个询问的顺序以此来降低复杂度. D. Powerful array 典型的莫队算法题 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include

Codeforces 57C Array dp暴力找规律

题目链接:点击打开链接 先是计算非递增的方案, 若非递增的方案数为x, 则非递减的方案数也是x 答案就是 2*x - n 只需求得x即可. 可以先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元即可. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #def

codeforces 797 E. Array Queries【dp,暴力】

题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为止,求每次询问要转换的次数. 题解:纯暴力会TLE,所以在k为根号100000范围内dp打表 dp[i][j]表示初始p为i, k为j,需要转换几次可以大于n. 状态转移方程:dp[i][j] = dp[i+a[i]+j] + 1 #include <cstdio> #include <al