Codeforces D. Powerful array(莫队)

题目描述:

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。

1     for(int i = 1;i<=bulk;i++)
2     {
3         for(int j = (i-1)*size+1;j<=i*size;j++)
4         {
5             belong[j] = i;
6         }
7     }

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

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

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

卡常技巧:

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

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

优化结果:

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

第二个为改cmp

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

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 #define max_n 200005
 5 using namespace std;
 6 int a[max_n];
 7 int cnt[1000005];
 8 int belong[max_n*2];
 9 int bulk;
10 int size;
11 long long ans = 0;
12 long long sum[max_n];
13 int n;
14 int m;
15 struct node
16 {
17     int r;
18     int l;
19     int id;
20 }q[max_n];
21 int cmp(node a,node b)
22 {
23     return (belong[a.l]==belong[b.l])?a.r<b.r:a.l<b.l;
24 }
25 int cmp2(node a,node b)
26 {
27     return (belong[a.l]^belong[b.l])?(a.l<b.l):(belong[a.l]&1)?a.r<b.r:a.r>b.r;
28 }
29 
30 void add(int pos)
31 {
32     ans -= (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
33     /*if(cnt[a[pos]]==0)
34     {
35         ans++;
36     }*/
37     cnt[a[pos]]++;
38     ans += (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
39 }
40 void del(int pos)
41 {
42     ans -= (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
43     cnt[a[pos]]--;
44     /*if(cnt[a[pos]]==0)
45     {
46         ans--;
47     }*/
48     ans += (long long)a[pos]*cnt[a[pos]]*cnt[a[pos]];
49 }
50 #pragma GCC optimize(2)
51 int main()
52 {
53     cin >> n >> m;
54     size = sqrt((double)n);
55     bulk = ceil((double)n/size);
56     for(int i = 1;i<=bulk;i++)
57     {
58         for(int j = (i-1)*size;j<=i*size;j++)
59         {
60             belong[j] = i;
61         }
62     }
63     for(int i = 1;i<=n;i++)
64     {
65         cin >> a[i];
66     }
67 
68     for(int i = 1;i<=m;i++)
69     {
70         cin >> q[i].l >> q[i].r;
71         q[i].id = i;
72     }
73     sort(q+1,q+m+1,cmp2);
74     /*for(int i = 0;i<n;i++)
75     {
76         cout << belong[i] << " ";
77     }
78     cout << endl;*/
79     int l = 1;
80     int r = 0;
81     for(int i = 1;i<=m;i++)
82     {
83         int nl = q[i].l;
84         int nr = q[i].r;
85         while(l>nl) add(--l);
86         while(r<nr) add(++r);
87         while(l<nl) del(l++);
88         while(r>nr) del(r--);
89         //cout << q[i].id << endl;
90         sum[q[i].id] = ans;
91     }
92     for(int i = 1;i<=m;i++)
93     {
94         cout << sum[i] << endl;
95     }
96     return 0;
97 }

参考文章:

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(莫队算法清晰简明讲解)

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

转载于:https://www.cnblogs.com/zhanhonhao/p/11224475.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值