题目描述:

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.

思路:

题目是要求给定一个区间,分别统计出区间不同数字的个数,对每个不同的数,求出现次数的平方与该数字的乘积的和。

因为给了好几组区间,很容易想到是一种直接暴力的算法,每个询问都统计一次然后算出一个ans来,但很显然这个算法会超时,因为对于不同的询问区间可能会有一部分重合的以求得的信息,每次暴力计算并没有利用这些已知信息。那么如何使用呢?想到既然是区间问题那不如用线段树来维护一个区间,但是,对于蒟蒻来说,我会做的线段树只能维护一些简单的信息,不会维护这种复杂的统计信息(我还是太菜了),怎么办呢?要知道,维护区间信息问题还有一种重要且巧妙的方法——莫队算法。

哈哈哈,知道了这个算法,虽然也是暴力算法,但是它通过分块+排序预处理能把复杂度降到O(n*sqrt(n)),就可以做了。注意在处理ans是改动一下就好

小心的是,如果用的分组方法是这种:就千万小心把belong数组开大一点,(两倍就行),因为它是刚好分成size*bulk,这么多元素,如果测试点是2e5(对这道题而言),那么最后belong原来的空间用完后会继续往下面的位置赋值,导致越界。(我在这卡了好久qwq)。还有cnt统计个数数组不能开long long。

     for(int i = ;i<=bulk;i++)
{
for(int j = (i-)*size+;j<=i*size;j++)
{
belong[j] = i;
}
}

(bulk是块数,size是每块的大小)

当然,下面这种分组方式就不存在问题,因为他刚好分n个元素。

 for(int i = ;i<=n;i++)
scanf("%d",&col[i]),Be[i]=i/unit+;

卡常技巧:

cmp函数改为莫队玄学奇偶性排序(代码中的cmp2),实际上可以帮你每个点平均优化200ms(可怕)

如果允许,吸氧也是极好的#pragma GCC optimize(2)

优化结果:

第一个为什么都不做(超时)

第二个为改cmp

第三个为改cmp+开optimize(2)

代码:

 #include <iostream>
#include <algorithm>
#include <cmath>
#define max_n 200005
using namespace std;
int a[max_n];
int cnt[];
int belong[max_n*];
int bulk;
int size;
long long ans = ;
long long sum[max_n];
int n;
int m;
struct node
{
int r;
int l;
int id;
}q[max_n];
int cmp(node a,node b)
{
return (belong[a.l]==belong[b.l])?a.r<b.r:a.l<b.l;
}
int cmp2(node a,node b)
{
return (belong[a.l]^belong[b.l])?(a.l<b.l):(belong[a.l]&)?a.r<b.r:a.r>b.r;
} void add(int pos)
{
ans -= (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
/*if(cnt[a[pos]]==0)
{
ans++;
}*/
cnt[a[pos]]++;
ans += (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
}
void del(int pos)
{
ans -= (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
cnt[a[pos]]--;
/*if(cnt[a[pos]]==0)
{
ans--;
}*/
ans += (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
}
#pragma GCC optimize(2)
int main()
{
cin >> n >> m;
size = sqrt((double)n);
bulk = ceil((double)n/size);
for(int i = ;i<=bulk;i++)
{
for(int j = (i-)*size;j<=i*size;j++)
{
belong[j] = i;
}
}
for(int i = ;i<=n;i++)
{
cin >> a[i];
} for(int i = ;i<=m;i++)
{
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q+,q+m+,cmp2);
/*for(int i = 0;i<n;i++)
{
cout << belong[i] << " ";
}
cout << endl;*/
int l = ;
int r = ;
for(int i = ;i<=m;i++)
{
int nl = q[i].l;
int nr = q[i].r;
while(l>nl) add(--l);
while(r<nr) add(++r);
while(l<nl) del(l++);
while(r>nr) del(r--);
//cout << q[i].id << endl;
sum[q[i].id] = ans;
}
for(int i = ;i<=m;i++)
{
cout << sum[i] << endl;
}
return ;
}

参考文章:

hzwer,「分块」数列分块入门1 – 9 by hzwer,http://hzwer.com/8053.html(分块算法)

WAMonster,莫队算法——从入门到黑题,https://www.cnblogs.com/WAMonster/p/10118934.html(莫队算法良心讲解)

大米饼,莫队算法,https://www.cnblogs.com/Paul-Guderian/p/6933799.html(莫队算法清晰简明讲解)

(两篇结合互补食用效果为佳)

Codeforces D. Powerful array(莫队)的更多相关文章

  1. Codeforces 86D - Powerful array(莫队算法)

    题目链接:http://codeforces.com/problemset/problem/86/D 题目大意:给定一个数组,每次询问一个区间[l,r],设cnt[i]为数字i在该区间内的出现次数,求 ...

  2. CodeForces - 86D Powerful array (莫队)

    题意:查询的是区间内每个数出现次数的平方×该数值的和. 分析:虽然是道莫队裸体,但是姿势不对就会超时.答案可能爆int,所以要开long long 存答案.一开始的维护操作,我先在res里减掉了a[p ...

  3. CodeForces 86 D Powerful array 莫队

    Powerful array 题意:求区间[l, r] 内的数的出现次数的平方 * 该数字. 题解:莫队离线操作, 然后加减位置的时候直接修改答案就好了. 这个题目中发现了一个很神奇的事情,本来数组开 ...

  4. CodeForces - 86D D. Powerful array —— 莫队算法

    题目链接:http://codeforces.com/problemset/problem/86/D D. Powerful array time limit per test 5 seconds m ...

  5. codeforces 86D,Powerful array 莫队

    传送门:https://codeforces.com/contest/86/problem/D 题意: 给你n个数,m次询问,每次询问问你在区间l,r内每个数字出现的次数的平方于当前这个数的乘积的和 ...

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

    题目链接: D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input stan ...

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

    莫队算法就是优化的暴力算法.莫队算法是要把询问先按左端点属于的块排序,再按右端点排序.只是预先知道了所有的询问.可以合理的组织计算每个询问的顺序以此来降低复杂度. D. Powerful array ...

  8. Yandex.Algorithm 2011 Round 2 D. Powerful array 莫队

    题目链接:点击传送 D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input ...

  9. [Codeforces86D]Powerful array(莫队算法)

    题意:定义K[x]为元素x在区间[l,r]内出现的次数,那么它的贡献为K[x]*K[x]*x 给定一个序列,以及一些区间询问,求每个区间的贡献 算是莫队算法膜版题,不带修改的 Code #includ ...

  10. Codeforces 86D Powerful array (莫队算法)

    题目链接 Powerful array 给你n个数,m次询问,Ks为区间内s的数目,求区间[L,R]之间所有Ks*Ks*s的和. $1<=n,m<=200000,   1<=s< ...

随机推荐

  1. [LeetCode] 114. Flatten Binary Tree to Linked List 将二叉树展平为链表

    Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 ...

  2. Python下numpy的使用

    首先:当然是欢迎大家了! Numpy : NumPy系统是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structur ...

  3. 关于ios手机上拉和下拉到底部和顶部的橡皮筋问题

    之前遇到一个问题,就是写了一个正常的移动端首页,底部是导航,上面的是内容,在安卓手机是页面滑动到底部的时候,不会再滑动的,但是问题就出现在ios手机中.页面正常布局是,导航是position:fixe ...

  4. jqGrid设置单选

    beforeSelectRow: function() { $(this).jqGrid('resetSelection'); return true; }

  5. 为文献管理软件Mendeley设置代理

    Mendeley由于某些原因无法在线同步,需要fq,在tools->option->connection中可以设置http代理或者sock5代理, sock5可以使用shadowsocks ...

  6. Kafka Streams | 流,实时处理和功能

    1.目标 在我们之前的Kafka教程中,我们讨论了Kafka中的ZooKeeper.今天,在这个Kafka Streams教程中,我们将学习Kafka中Streams的实际含义.此外,我们将看到Kaf ...

  7. Java开发笔记(一百一十九)AWT布局

    前面介绍了如何在窗口上添加一个按钮,可是每个软件界面都包含了许多控件,这些控件又是按照什么规则在界面上排列的呢?仍以按钮为例,假如要在窗口上依次添加多个按钮,那么界面会怎样显示这些按钮?想当然的话,按 ...

  8. SQL——函数

    演示c_grade表 一.AVG() AVG()函数用于返回数值列的平均值 例: SELECT AVG(score) FROM c_grade; 运行结果: 通过运行结果可以看到,score字段为Nu ...

  9. 【Linux】一步一步学Linux——Centos7.5安装图解(08)

    00. 目录 参考博客:https://mp.csdn.net/mdeditor/95031775# 01. Centos7.5简介 CentOS(Community Enterprise Opera ...

  10. UI测试用例设计,场景测试法

    百度一番,没有发现详细的UI测试用例设计方法,只能自己整理一下,学习.改进. 那么正题来了,我们慢慢缕下思路: 1.整理要测实体中的,处理逻辑.触发规则.动作. 2.将场景测试抽象出来 3.到这个时候 ...